HRR Co., Ltd.

技術的な記録を残していくことを目的としています。1次情報を大事にしています。

WSL2上でopenコマンドを実行できるようにする

はじめに

WSL2上で、いわゆるopenコマンドを実行できるようにします。
ディレクトリを指定すればディレクトリをエクスプローラーで開く、ファイルを指定すればファイルを開く、そんな動きをします。

openコマンド実装まで

1. cmd.exe へのパスを通す

vi ~/.profile
# path to Windows
export PATH=$PATH:/mnt/c/Windows/System32

デフォルトではcmd.exeは実行できない(パスが通っていない)と思うの で、.profileに書き込むことでパスを通します。

追記したら、再読み込みを忘れずに。

source ~/.profile

2. .bashrcにてopen関数を作成

自前の関数を定義します。ソースコードは下記の通り。
シェルの起動時に定義した関数を使えるように、.bashrcに記載します。

コードの解説は後ほど。

vi ~/.bashrc  
function open() {
    path_name=$1
    if [ $# -eq 0 ]; then
        path_name="."
    elif [ $# -gt 1 ]; then
        echo "open: $* : Set only one directory or file path" 1>&2
        return 1
    fi

    if [ -e "${path_name}" ]; then
        cmd.exe /c start $(wslpath -w ${path_name}) 2> /dev/null
    else
        echo "open: ${path_name} : No such file or directoty" 1>&2
        return 1
    fi

    return 0
}

こちらも、再読み込みを忘れずに。

source ~/.bashrc

3. 使ってみる

# 現在のディレクトリをエクスプローラーで開く
open .

# 現在のディレクトリをエクスプローラーで開く
# (引数なしでもいけるようにしています。エラーにしてもいいんですが)
open

# 指定のディレクトリをエクスプローラーで開く
# (変換をかけるので、WSL2上のパスで構いません)
open ~/work/

# 指定のファイルを規定のプログラムで開く
# (.bashrcなどを指定すると、Windows側でどのプログラムで開くか聞かれるかも)
open ~/work/memo.txt

# Windows側のexeファイルを実行することも可能です
# (下記の例はメモ帳を立ち上げています)
open /mnt/c/Windows/System32/notepad.exe

コードの解説

bashのマニュアルも見るとよいと思います。

linuxjm.osdn.jp

function open() {
    # 第一引数($1)を変数に格納しておきます
    path_name=$1

    # $#: 引数の数を表します。
    if [ $# -eq 0 ]; then
        # 引数の数が0なら、パスを現在のディレクトリに指定します。
        # エラーにしてもよいと思ってますが今回は救済してみました。
        path_name="."
    elif [ $# -gt 1 ]; then
        # 引数の数 > 1 の場合にはエラーにすることにしました。
        # $*: 引数すべてを列挙します。
        echo "open: $* : Set only one directory or file path" 1>&2
        # 終了ステータスを返す(0以外は失敗なので今回は1を返す)
        return 1
    fi

    # パスの存在チェックを行っています
    if [ -e "${path_name}" ]; then
        # コマンドプロンプトでファイルを開きます。
        cmd.exe /c start $(wslpath -w ${path_name}) 2> /dev/null
    else
        # 有効なパスでなければ、エラーを吐きます。
        # 標準エラー出力に出るように調整しています。
        echo "open: ${path_name} : No such file or directoty" 1>&2
        # 終了ステータスを返す(0以外は失敗なので今回は1を返す)
        return 1
    fi

    # 終了ステータスを返す(0が成功)
    return 0
}

詳細: コマンドプロンプトの操作について

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

について、詳しく説明します。

wslpath について

恐らく最初から用意されているコマンドです。使い方はこんな感じです(Usageを表示してみました)。

$ wslpath
wslpath: Invalid argument
Usage:
    -a    force result to absolute path format
    -u    translate from a Windows path to a WSL path (default)
    -w    translate from a WSL path to a Windows path
    -m    translate from a WSL path to a Windows path, with '/' instead of '\'

EX: wslpath 'c:\users'

wslpath -w ${path_name} を実行することで、Linux的なパスをWindowsのパスに変換して、cmd.exeに渡してあげています。

cmd.exe 部分について

あまり見慣れないかもしれませんが、コマンドプロンプトで実行できるコマンドをexeファイルを通して実行していることになります。

startについてはこちらをご参照ください。

learn.microsoft.com

start は、指定された実行可能ファイルを検索し、見つかった場合は、現在の作業ディレクトリに関係なく実行可能ファイルを起動します。 実行可能ファイルを検索して、どの拡張子にも一致するものがないと、start は名前がディレクトリ名と一致するかどうかを調べます。 そのような場合は、 開始 そのパスに Explorer.exe を開きます。

上記引用部分が今回の使い方になります。

終わりに

WSL2とのやり取りをしたい場合はそこそこ発生するので、一度openを実装してしまえば便利なツールとして使えると思います。
またご自分で使いやすいようにいじってもらえるとよいと思います。

以上でした!