wait-forは、端末が指定した状態になるまで待つサブコマンドである。エミュレータの起動や端末の再起動を待ってから次のコマンドを実行したい場合など、スクリプトで使う。

wait-for[-TRANSPORT]-STATE...
    wait for device to be in a given state
    STATE: device, recovery, rescue, sideload, bootloader, or disconnect
    TRANSPORT: usb, local, or any [default=any]

端末の接続を待つ

wait-for-deviceは、端末がdevice状態になるまで待つ。すでにdevice状態の端末があれば、すぐに終了する。USBデバッグを許可していないunauthorized状態の端末では、許可されるまで待ち続ける。

$ adb wait-for-device

wait-for-...の後ろに別のコマンドを続けると、指定した状態になってから実行される。

$ adb -s emulator-5554 wait-for-device shell getprop ro.build.version.release
16

起動完了まで待つ

wait-for-deviceは起動処理の完了を待たない。エミュレータをコールドブートした場合、wait-for-deviceはエミュレータの起動開始から約11秒で終了し、sys.boot_completedが1になるのは約28秒後である。

アプリのインストールなど、起動完了後に実行したい処理がある場合はsys.boot_completedが1になるまで待つ。

$ adb wait-for-device shell 'while [ "$(getprop sys.boot_completed)" != 1 ]; do sleep 1; done'

切断を待つ

wait-for-disconnectは、端末が一覧から消えるか、offlineなど通信できない状態になるまで待つ。adb rebootの後に使うと、再起動の開始を確認できる。

$ adb reboot
$ adb wait-for-disconnect
$ adb devices
List of devices attached
emulator-5554	offline

上記のとおり、adb devicesの一覧から消える前のoffline状態でも終了する。対象の端末が接続されていない場合や、すでにoffline・unauthorizedの場合はすぐに終了する。

adb rebootの直後にwait-for-deviceを実行すると、再起動前のdevice状態を拾う可能性がある。wait-for-disconnectを挟むと確実に再起動後の状態を待てる。

$ adb reboot && adb wait-for-disconnect && adb wait-for-device

参考: 【adb】rebootで端末を再起動する・bootloaderやrecoveryで起動する

USB接続・TCP/IP接続を区別して待つ

wait-forと状態の間にusbまたはlocalを入れると、接続方法を限定できる。usbはUSB接続の端末、localはエミュレータやadb connectで接続した端末などTCP/IP経由の端末を対象とする。

$ adb devices
List of devices attached
[実機のシリアル]	device

$ adb wait-for-usb-device
$ adb wait-for-local-device
# エミュレータが起動するまで終了しない

上記の状態では、USB接続の実機がdevice状態のためwait-for-usb-deviceはすぐに終了する。wait-for-local-deviceはエミュレータが起動するまで待ち続ける。

複数の状態のいずれかを待つ

ヘルプのSTATE...が示すとおり、状態は-でつなげて複数指定できる。いずれかの状態になった時点で終了する。以下はdeviceまたはrecoveryのどちらかになるまで待つ例である。

$ adb wait-for-device-recovery

存在しない状態を指定するとエラーになる。接続方法を省略した場合はanyが補われるため、エラーメッセージにはany-が付く。

$ adb wait-for-foo
error: bad wait-for- state: any-foo

複数の端末が接続されている場合

複数の端末が接続されている状態で-sを付けずに実行すると、エラーになる。

$ adb wait-for-device
error: more than one device/emulator

-sでシリアルを指定すると、指定した端末だけを待つ。USB接続とTCP/IP接続の端末が1台ずつなら、wait-for-usb-device・wait-for-local-deviceでもエラーを避けられる。指定したシリアルの端末がまだ接続されていない場合は、接続されるまで待つ。

$ adb -s emulator-5554 wait-for-device

タイムアウトを設定する

wait-for自体にはタイムアウトの設定がない。端末が接続されなければ終了しないため、スクリプトではtimeoutコマンドと組み合わせる。タイムアウトした場合、timeoutは終了コード124を返す。

$ timeout 60 adb wait-for-local-device
$ echo $?
124

macOSにはtimeoutコマンドが標準で入っていないため、Homebrewのcoreutilsをインストールする。

$ brew install coreutils

参考