WSLで大抵のことは完結できるようになってきましたが、ときどきWindows側の.exeを使いたくなるときがあります。 その方法を説明します。


例えばUSB接続したAndroid端末を制御するにはAndroid デバッグツールadbを使います。 ですがWSLのadbを実行してもデバイスを見つけられず下記のようなエラーになります。

1
2
$ adb devices
adb: no devices/emulators found

このような場合はWSL内のツールでは操作は難しいので素直にWindows側のadb.exeを実行したほうが楽です。 単純に使うだけなら.exeをWSLから実行すればいいのですがいくつかはまりポイントがあります。 そこで今回は Windows ネイティブの adb.exe を例に WSL からWindowsの .exeを使うコツを説明します。 今回は adb.exeを例にしていますが、別のツールでも基本的に一緒のはずです。 ぜひ参考にしてください。

Windows 用の. exe ダウンロード

まずなにはともあれ .exe が必要です。adbは、SDK Platform-Tools からダウンロードします。

platform-tools-latest-windows.zip をダウンロードしたら、任意のフォルダに展開します。 その中には adb.exe や fastboot.exe が含まれているはずです。 奥場所はどこのフォルダでもいいのですが、Program Filesのようなフォルダ名にスペースがある 正気を疑うネーミングの ところは避けたほうがよいです。 今回はc:\Programs\platform-tools\に置いたことにします。 エスケープが面倒なのでスペースをフォルダ名、ファイル名に入れないほうが幸せになれると思います。

さらにWindows環境変数(not WSL)のPATHにも設定しておきます。 【Windows 10/11】Path環境変数の設定で「あのコマンド、どこだっけ?」をなくす、Windows効率向上の最強テクニックの記事が参考になるかと思います。

WSL のパス設定

WSL はデフォルトで Windows 側のパス設定を引き継ぐ仕様なので特に何もせずとも adb.exeが使えるはずです。 下記のように which コマンドで adb.exe が見つかればOKです。

1
2
$ which adb.exe
/mnt/c/Programs/platform-tools/adb.exe

もし使えない場合は .bashrc などで PATH 変数に追記してください。 今回の例だと下記のように記載すれば良いです。

1
PATH=$PATH:'/mnt/c/Programs/platform-tools/'

文字コード変換

adb.exe は Windowsの住人なので改行が LF でなくCRLF です。 そのため WSL側から実行してパイプに渡したりすると意図しない挙動をすることがあります。 たとえば adb devices の結果から末尾の空行を削除しようと下記のように trをつけても削除されません。 5行目に空行が入ったままですね。

1
2
3
4
5
6
$ adb.exe devices | tr -s "\n"
List of devices attached
HOGEHOGE01      device
HOGEHOGE02      device

$

そこで文字コード変換するために nkf を導入します。 Ubuntuの場合は aptでインストールできます。

1
sudo apt install nkf

下記のように nkf をパイプでつなげれば改行文字をCRLF → LFにできます。 オプション -Lu が改行をLFにするオプションです。ちなみに -w はUTF8への変換です。

1
2
3
4
5
$ adb.exe devices | nkf -Lu -w | tr -s "\n"
List of devices attached
HOGEHOGE01      device
HOGEHOGE02      device
$

環境変数の共有 WSLENV

下記の例のように複数のデバイスが接続されている場合、任意の1つを指定する必要があります。

1
2
3
4
$ adb.exe devices
List of devices attached
HOGEHOGE01      device
HOGEHOGE02      device

指定しないと下記のように、複数のデバイスがあると怒られてしまいます。

1
2
$ adb.exe shell whoami
adb.exe: more than one device/emulator

デバイス指定の1つの方法として -sオプションでシリアルを指定する方法があります。

1
2
$ adb.exe -s HOGEHOGE01 shell whoami
root

これでもいいのですが毎回 -s をつけるのは面倒です。 adb のヘルプを見ると下記の環境変数があると説明があります。

$ANDROID_SERIAL serial number to connect to (see -s)

ですが下記のようにしてもうまくいきません。

1
2
$ ANDROID_SERIAL=HOGEHOGE01 adb.exe shell whoami
adb.exe: more than one device/emulator

これは adb.exe がWindowsの住人なので WSL の環境変数の効果がないためです。 こで下記のように WSLENVも設定します。 WSLENVを設定するとその設定が Windows側にも環境変数が共有され 期待通り動作します。

1
2
3
4
$ export WSLENV=ANDROID_SERIAL:HOGEHOGE01
$ export ANDROID_SERIAL=HOGEHOGE01
$ adb.exe shell whoami
root

WSLENV の詳細は WSLENV を使用して Windows と WSL の間で環境変数を共有するを参照してください。

PATH形式変換 wslpath

Windowsの.exeに引数を渡すときはパスの形式に注意が必要です。 WSL 側では /mnt/c/Programs/platform-tools/ という表記の場合、 Windows側ではC:\Programs\platform-tools\ となります。 なのでWindowsの住人であるadb.exeに、下記のようなWSL(というかUNIX/Linux)のパス形式で渡すとエラーになります。

1
adb.exe push /mnt/c/User/username/Download/hoge.bin /data/

これを解決するのが wslpath です。 例えば下記のように-w オプションで渡すとWindows形式に変換してくれます。

1
2
$ wslpath -w  /mnt/c/User/username/Download
C:\Users\username\Downloads

これを利用して下記のようにすると正しく adb.exehoge.binのパスを認識してくれます。

1
adb.exe push $( wslpath -w /mnt/c/User/username/Download/hoge.bin ) /data/

WSL と Ubuntuの共存

ここまでくると普通のLinuxとWSLとで同じスクリプトを共有したいという要望が出てくるかもしれません。 下記にその例を書いておきます。uname -r microsoft が含まれればWSL、なければ普通のLinuxです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# adb パス設定
if { which adb || which adb.exe } > /dev/null ; then
    ADB=$(which adb || which adb.exe)
fi

# WSLの環境変数をWindowsに共有する設定
ANDROID_SERIAL='hogehoge'
export WSLENV=ANDROID_SERIAL:${ANDROID_SERIAL}
export ANDROID_SERIAL=${ANDROID_SERIAL}

# WSL のときだけWindows形式にパス変換
# WSL は uname -r が 5.15.153.1-microsoft-standard-WSL2のように microsoft が含まれる
DATA=/mnt/c/User/username/Download/hoge.bin
${ADB} push $( [[ "$(uname -r)" == *microsoft* ]] && wslpath -w "${DATA}" || echo "${DATA}") /data/

まとめ

今回は adb を例に、 WSLからWindowsネイティブの.exeを使う方法を説明しました。

  • 改行コードに注意する
  • WSLENVで環境変数を共有
  • uname -r にmicrosoftが含まれればWSL、なければ普通のLinux

というのを覚えておいてください!