独自のパッケージマネージャによってインストールされたWSL上のコマンドをWindowsから呼び出す方法

WindowsからWSL上のコマンドを呼び出す一般的な方法

WSLにインストールしたコマンドをWindowsから呼び出したくなるときがあります。

適当に調べると

wsl ls -aのように、wslコマンドの後ろに普通にコマンドを書けば実行できるよ

と紹介する記事などが沢山出てくると思います。

実際、wsl --helpとしたときに、一番上に

使用法: wsl.exe [引数] [オプション...] [コマンドライン]

Linux バイナリーを実行する引数:

コマンド ラインがない場合、wsl.exe は既定のシェルを起動します。

--exec, -e <コマンドライン> 既定の Linux シェルを使用せずに、指定されたコマンドを実行します。

と表示され、Microsoftの公式サイトでも"Run Linux tools from a Windows command line"という項目が存在し、

For example:

C:\temp> wsl ls -la <- contents of C:\temp ->

という例が出てきます。

勿論、手元で

> wsl ls

とするときちんとファイルやフォルダが表示されます。

WSL上のコマンドが呼び出せない……?

さて、ここでRustというプログラミング言語コンパイラであるrustcコマンドを実行させてみたいと思います(勿論、WSL上にインストールしてあるコンパイラです)。

> wsl rustc --version

すると、結果は

/bin/bash: rustc: command not found

となります。

あれ……?

WSL上ではしっかりとrustcはインストールしてあり、試しにWSLを起動してそのうえでバージョンを確認してみるとしっかりと表示されます。

> wsl
$ rustc --version
rustc 1.54.0 (a178d0322 2021-07-26)

これはrustfmtcargorustupなどでも発生しました。

また、OCaml関連でインストールしたdunemenhirといったコマンドも同じく、command not foundと怒られてしまいました。

ところが、OCamlのパッケージマネージャであるopamWindows側から起動させることができました。

つまり、Windowsからwsl <command>構文を使って起動させることができるものと、起動させられないものが存在するのです。

解決方法(とりあえずの)

呼び出すことができないrustcと呼び出すことができるopam、という点に着目しました。

whichコマンドを使ってそれぞれのバイナリファイルの置き場所を見てみました。すると

$ which rustc
/home/puripuri2100/.cargo/bin/rustc

$ which opam
/usr/local/bin/opam

$ which ls
/usr/bin/ls

となりました。

どうやら、/usr/bin/以下か/usr/local/bin/以下のフォルダに実行ファイルが存在すると呼び出せそうな雰囲気があります。

というわけで実行ファイルを/usr/local/bin/以下にコピーしたいのですが、そのままコピーするとバイナリファイルをアップデートした際に困ります。なので、これを回避するためにシンボリックリンクを設置することにしました。

シンボリックリンクlnコマンドによって設置できますので、以下のようにして設定してみました。

$ sudo ln -s /home/puripuri2100/.cargo/bin/rustc /usr/local/bin/rustc

さて、ここで試しにWindows側から呼び出してみます。

> wsl rustc --version
rustc 1.54.0 (a178d0322 2021-07-26)

今度はきちんと表示されました。

どうやら「/usr/local/bin/以下に実行ファイルへのシンボリックリンクを貼る」という解決方法は一応機能するようです。(その後、rustcをアップデートした後にもう一度Windows側から呼び出してみると、きちんと動作しました。)

まとめ

  • WindowsからWSL上のコマンドを呼び出すにはwsl <command>という使い方をすれば良いが、それでも呼び出すことができないものが存在する
  • wsl <command>をすると、/usr/bin/usr/local/binなどしか見に行かないため、パッケージマネージャ独自のフォルダに実行ファイルが入っている場合は呼び出すことができない
  • /usr/local/bin以下に起動したい実行ファイルへのシンボリックリンクを設置することでWindowsからの呼び出しができるようになる
  • 実行ファイルへのリンクができただけなので、それ以外のライブラリ関係についてなどはよくわかりません
  • 公式情報が欲しいですね