WSL は大変便利で大抵のことはその中で完結できますが、ときどき Windows側の .exe を使いたくなるときがあります。
例えばUSB接続したAndroid端末を制御するにはAndroid デバッグツール adb を使います。ですがWSLのadbを実行してもデバイスを見つけられず下記のようなエラーになります。
$ adb devices adb: no devices/emulators found
このような場合はWSL内のつーるでは操作は難しいので素直にWindows側のadb.exeを実行したほうが楽です。単純に使うだけなら.exeをWSLから実行すればいいのですがいくつかはまりポイントがあります。
そこで今回は Windows ネイティブの adb.exe を例に WSL からWidowsの .exe を使うコツを説明します。
今回は adb.exe を例にしていますが、別のツールでも基本的に一緒のはずです。
是非参考にしてください。
Windows 用の. exe ダウンロード
まずなにはともあれ .exe が必要です。adbの場合は、下記の Windows のPlatform tools をダウンロードします。
下記のサイトから入手できます。
platform-tools-latest-windows.zip をダウンロードしたら、任意のフォルダに展開します。
その中にはadb.exe や fastboot.exe が含まれているはずです。
奥場所はどこのフォルダでもいいのですが、Program Files のようなフォルダ名にスペースがある 正気を疑うネーミングの ところは避けたほうがよいです。今回は c:\Programs\platform-tools\
に置いたことにします。エスケープが面倒なのでスペースをフォルダ名、ファイル名に入れないほうが幸せになれると思います。
さらにWindows 環境変数のPATHにも設定しておきます。下記の記事が参考になるかと思います。
WSL のパス設定
WSL はデフォルトで Windows 側のパス設定を引き継ぐ仕様なので特に何もせずとも adb.exe が使えるはずです。
下記のように which コマンドで adb.exe が見つかればOKです。
$ which adb.exe /mnt/c/Programs/platform-tools/adb.exe
もし使えない場合は .bashrc などで PATH 変数に追記してください。
今回の例だと下記のように記載すれば良いです。
PATH=$PATH:'/mnt/c/Programs/platform-tools/'
文字コード変換
adb.exe は Windowsの住人なので改行が LF でなく CRLF です。そのため WSL 側から実行してパイプに渡したりすると意図しない挙動をすることがあります。
たとえば adb devices の結果から末尾の空行を削除しようと下記のように tr をつけても削除されません。5行目に空行が入ったままですね。
$ adb.exe devices | tr -s "\n" List of devices attached HOGEHOGE01 device HOGEHOGE02 device $
そこで文字コード変換するために nkf を導入します。apt でインストールできます。
$ sudo apt install nkf
下記のように nkf をパイプでつなげれば改行文字をCRLF → LFにできます。 オプション -Lu が改行をLFにするオプションです。 ちなみに -w はUTF8への返還です。
$ adb.exe devices | nkf -Lu -w | tr -s "\n" List of devices attached HOGEHOGE01 device HOGEHOGE02 device $
環境変数の共有 WSLENV
下記の例のように複数のデバイスが接続されている場合、任意の1つを指定する必要があります。
$ adb.exe devices List of devices attached HOGEHOGE01 device HOGEHOGE02 device
指定しないと下記のように、複数のデバイスがあると怒られてしまいます。
$ adb.exe shell whoami adb.exe: more than one device/emulator
デバイス指定の1つの方法として -s オプションでシリアルを指定する方法があります。
$ adb.exe -s HOGEHOGE01 shell whoami root
これでもいいのですが毎回 -s をつけるのは面倒です。
adb のヘルプを見ると下記の環境変数があると説明があります。
$ANDROID_SERIAL serial number to connect to (see -s)
ですが下記のようにしてもうまくいきません。
$ ANDROID_SERIAL=HOGEHOGE01 adb.exe shell whoami adb.exe: more than one device/emulator
これは adb.exe がWindowsの住人なので WSL の環境変数の効果がないためです。
そこで下記のように WSLENV も設定します。WSLENVを設定すするとその設定が Windows 側にも環境変数が共有され期待通り動作します。
$ export WSLENV=ANDROID_SERIAL:HOGEHOGE01 $ export ANDROID_SERIAL=HOGEHOGE01 $ adb.exe shell whoami root
WSLENV の詳細下記を参照してください。
https://learn.microsoft.com/ja-jp/windows/wsl/filesystems#share-environment-variables-between-windows-and-wsl-with-wslenv
PATH形式変換 wslpath
Windowsの.exeに引数を渡すときはパスの形式に注意が必要です。WSL 側では /mnt/c/Programs/platform-tools/ という表記の場合、Windows側では C:\Programs\platform-tools\ となります。
なのでWindowsの住人であるadb.exeに、下記のようなWSL(というかUNIX/Linux)のパス形式で渡すとエラーになります。
$ adb.exe push /mnt/c/User/username/Download/hoge.bin /data/
これを解決するのが wslpath です。例えば下記のように-w オプションで渡すとWindows形式に変換してくれます。
$ wslpath -w /mnt/c/User/username/Download C:\Users\username\Downloads
これを利用して下記のようにすると正しく adb.exe が hoge.bin のパスを認識してくれます。
$ adb.exe push $( wslpath -w /mnt/c/User/username/Download/hoge.bin ) /data/
WSL と Ubuntuの共存
ここまでくると普通のLinuxとWSLとで同じスクリプトを共有したいという要望が出てくるかもしれません。
下記にその例を書いておきます。ポイントはかきの3つです。
* uname -r に microsoft が含まれればWSL、なければ普通のLinux
* WSLENVで環境変数を共有
* PATHはwslpathで変換
# adb パス設定 if { which abd || which abd.exe } > /dev/null ; then ADB=$(which abd || which abd.exe) fi # WSLの環境変数をWindowsに共有する設定 ANDROID_SERIAL='hogehoge' export WSLENV=ANDROID_SERIAL:${ANDROID_SERIAL} export ANDROID_SERIAL=${ANDROID_SERIAL} # WSL のときだけWidows形式にパス変換 # WSL は uname -r が 5.15.153.1-microsoft-standard-WSL2のように microsoft が含まれる DATA=/mnt/c/User/username/Dowload/hoge.bin ${ADB} push $( [[ "$(uname -r)" == *microsoft* ]] && wslpath -w "${DATA}" || echo "${DATA}") /data/
まとめ
今回は adb を例に、 WSL からWindowsネイティブの.exeを使う方法を説明しました。
* 改行コードに注意する
* uname -r に microsoft が含まれればWSL、なければ普通のLinux
* WSLENVで環境変数を共有
* PATHはwslpathで変換
がコツです。ぜひご活用ください。
コメント