TL;DR

WSLでMacのopenコマンドみたいなのが欲しければ、以下を.zshrcに書く。

function open() {
    if [ $# != 1 ]; then
        explorer.exe .
    else
        if [ -e $1 ]; then
            explorer.exe $(wslpath -w $1) 2> /dev/null
        else
            echo "open: $1 : No such file or directory" 
        fi
    fi
}

zshでしか試していないが、たぶんbashでも似たような感じでいけると思う。

動作原理

Macのターミナルでは、open filenameとすると、そのファイルを関連付けられたアプリで開くことができる。また、open .などとするとFinderでカレントディレクトリが開いて便利だ。

WindowsのWSLで似たようなことがしたくて、

alias open=explorer.exe

としていた。これでもほとんどの場合はうまくいくのだが、二つ問題があった。

一つは、デスクトップに同名のファイルがあるとそちらを開いてしまうこと。おそらくエクスプローラーのパスの検索順の問題だと思われる。

もう一つは、カレントディレクトリ以外のファイルを開けない事。例えば、カレントディレクトリにhoge.pdfがあるなら

open hoge.pdf

はできるが、

open dir/hoge.pdf
open ../hoge.pdf

などはできない。そこで、wslpath -wでパスを解決してからexplorer.exeにわたすことで、カレントディレクトリ以外のファイルにも対応している。

まず引数の数をチェックし、引数なしの場合はカレントディレクトリを開くようにする。

function open() {
    if [ $# != 1 ]; then
        explorer.exe .
    fi
}

次に、引数が指定された場合、そのファイルの存在確認をしよう。ファイルがあればそのまま開き、そうでなければエラーを表示する。

if [ -e $1 ]; then
    explorer.exe $(wslpath -w $1) 2> /dev/null
else
    echo "open: $1 : No such file or directory" 
fi

以上をまとめると冒頭のコマンドになる。

cmd.exeによるopen

:::message alert 2024年12月10日現在、cmd.exeからWSL上のファイルが開けなくなった。セキュリティの問題?以下は古い情報。 :::

ということを愚痴ったら、「cmd.exeを使うのはどうか?」という方法を教えていただいた

cmd.exe /c start filename

として実行することで、ファイルを開くことができる。ただし、wslpathを使って、WSLのパスをWindows側に変換してやる必要がある。そこで、シェルの関数にして

function open() { cmd.exe /c start $(wslpath -w $1) }

とすれば、ほぼ所望の動作になる。

しかし、これでファイルを開くと、いちいち

$ open test.pdf
'\\wsl.localhost\Ubuntu\home\username\path\to\file'
上記の現在のディレクトリで CMD.EXE を開始しました。
UNC パスはサポートされません。Windows ディレクトリを既定で使用します。

と言われてしまう。また、存在しないファイルを指定した場合、コマンドプロンプトが開いてしまう。さらに、引数を指定しないで実行した場合「このusageリンクを開くには新しいアプリが必要です」みたいなダイアログが出てしまう。

そこで

cmd.exe /c start $(wslpath -w $1) 2> /dev/null

とすることでメッセージを隠す。

参考URL