ByteScope

input text

端末を変える

いまフォーカスがある入力欄に文字列を打ち込みます。

コマンド
adb shell input text
コマンド
入力とタッチ
リスク
端末を変える

構文

input text <string>

使用例

  • input text 'hello world'

    引用してください。シングルクォートの中ではシェルは何にも手を出しません。

  • input text 'user@example.com'

    端末側ではなく本物のキーボードからログイン欄を埋めます。

  • input keyevent 66

    `input text` は改行を打たないので、後で Enter を押します。

出力の読み方

何も出ません。文字が端末に現れるか、現れないかで、どちらの報告もないので画面を見てください。

出力フィールド

フィールド意味
(no output)コマンドは実行されました。文字が届いたかどうかは端末の画面でしか分かりません。

必要な権限

認可済みの `adb` 接続だけで足ります。root も `adb root` も `su` も、USB デバッグ以外に開発者向けオプションで入れるものもありません。`input` は `cmd input "$@"` を実行するだけの 1 行のシェルスクリプト(AOSP の `cmds/input/input.sh`)なので、文字は `shell` ユーザーの身元で注入され、その背後に立つプラットフォーム権限は `android.permission.INJECT_EVENTS`、`com.android.shell` が自身のマニフェストで与えられているものです。この付与が意図して含んでいないのは、狙いを付ける手段です。`runText` が受け取るのは入力ソース、任意の `-d <displayId>`、そして文字列だけで、対象のアプリや activity や入力欄を名指しする引数は存在しません。文字は、届いた瞬間にそのディスプレイでフォーカスを持っている場所に落ちます。だからスクリプトでは、アクセス権よりも間合いと順序のほうがはるかに重要になります。目を離した隙に出たダイアログは、あなたのパスワードが打ち込まれる場所として完全に正当です。しかも待てる応答がありません。`sendText` は各イベントを注入側に渡すだけで結果を見ないので、下流が 1 打鍵でも消費したかを知らないままコマンドは終了します。正直な確認手段は `screencap` だけです。

エラーメッセージの読み解き

メッセージ意味
java.lang.IllegalArgumentException: Argument expected after "text"`runText` が必須の引数を要求したのに何もなかったので、`input text` の後ろが空だと例外になります。行は `Exception occurred while executing 'text':` のバナーとスタックトレースを伴って、すべて標準エラーに届きます。これが「空文字列ではない」ことに注意してください。`input text ''` は合法な、引用された空の引数で、静かに何もしません。
Exception occurred while executing 'text':shell command のハンドラが `Throwable` を捕まえ、バナーの次の行がそれを名指しします。非 ASCII の場合はここで終わります。`KeyCharacterMap.getEvents` は、現在のキー文字マップでは生成できない文字配列に対して null を返すと文書化されていて、このページのために読んだソースは null を確認せずに `events.length` を辿ります。つまり `é` や `日本語` を含む文字列は、途中まで打つのではなく `NullPointerException` を投げます。古いビルドではもっと静かに失敗すると報告されていて(下の注意を参照)、このページが非 ASCII を試す前に断るのはまさにそのためです。
Error: Invalid arguments for display ID.`-d` に整数でも `DEFAULT_DISPLAY` でも `INVALID_DISPLAY` でもないものが渡されました。1 文字も送る前、解析の段階で投げられるので、何も打たれていません。見るべきは文字列ではなく `-d` の次のトークンです。
cmd: Can't find service: input`input.sh` は `cmd input` の薄い包みでしかないので、`cmd` がサブコマンドを渡す先の `input` サービスを見つけられませんでした。起動途中、`system_server` がそれを公開する前なら想定内で、同じ時点で `settings` や `window` のサービスが返すのと同じ形の失敗です。

何が変わるか、そして戻る道

端末上のものが削除されることはありませんが、入力した文字はその瞬間フォーカスを持っているものすべてに届きます。チャットのメッセージ、検索ボックス、ログインやパスワードの欄、あるいは最後に画面を見てから出てきた確認ダイアログなどです。いったん送信されると取り消せません。まだ送信されていなければ、`input keyevent 67`(Delete)で 1 文字ずつ消せます。フォームを送信するのは `input keyevent 66`(Enter)です。入力する前に画面を確認し、欄に残っては困る秘密の文字列は送らないでください。

バージョンとメーカーに関する注意

  • ASCII のみで、これはケーブルやシェルではなくプラットフォームのコマンドの制限です。`input text` は印字可能な ASCII にしかキーを持たない仮想キーボードの文字マップで終わるので、日本語・中国語・アクセント付き文字はキーイベントを何も生みません。デスクトップの adb でも打てません。
  • 引数の中の `%s` は、キーボードが見る前に `input` 自身が空白に変えます。しかも `%%s` はパーセント記号と空白になるので、逃げ道はありません。1 回の呼び出しの中で `%` と `s` が隣り合わないように文字列を分けてください。
  • シングルクォートはアポストロフィを運べません。そこで文字列を切り、アポストロフィは `input keyevent 75` で送ります。`'\''` のような細工は、写し間違いが起きる類のものです。
  • 引数を引用していれば空白に `%s` は不要です。シェルが 1 つの語の中に空白を保ち、キーボードがそれをスペースキーに対応させます。

これには UI があります

Android ADB Toolbox はこのコマンドを USB 経由で実行し、返ってきたものを解析します。Chromium 系ブラウザだけで、SDK も不要、どこにもアップロードしません。

Android ADB Toolbox を開く

関連コマンド

input text と同じ作業で出てくるコマンド。

コマンド何をするか
input keyeventハードウェアキーや仮想キーを押します。Home、Back、電源、音量、Enter など。
geteventカーネルから生の入力イベントを流し読みします。各入力デバイスが何を報告できるかの一覧も取れます。
am startコンポーネント指定または intent 指定でアクティビティを起動します。ディープリンクの解決を確かめる最短経路です。

Web ADB ツール群のパーサを書きながら、AOSP・toybox・カーネルのソースに突き合わせて確認しています。バージョンやメーカーで本当に挙動が変わるところは、世界の半分の端末で間違いになる数値を出す代わりに、そう書いてあります。

よくある質問

adb shell のコマンドはどう実行しますか?

端末で開発者向けオプションと USB デバッグを有効にし、ケーブルを繋いだうえで、platform-tools を入れた機械から adb shell <コマンド> を実行します。adb shell だけを実行すれば対話プロンプトが出て、接頭辞なしで打てます。スクリーンショットのようにバイナリを出力するコマンドでは adb shell ではなく adb exec-out を使ってください。素のシェルサービスは端末を割り当て、それが改行のバイトを書き換えてデータを壊します。

adb shell のコマンドに root は必要ですか?

このリファレンスにあるものには不要です。すべて shell ユーザーとして動き、自分の Android ユーザー向けのパッケージ管理、ほとんどの dumpsys サービスの読み取り、設定プロバイダへの書き込み、入力の注入、共有ストレージの読み取りができます。root が必要なのはこのリファレンスがあえて避けていること、つまり他のアプリのプライベートデータの読み取り(debuggable なビルドに対する run-as を除く)、システムパーティションへの書き込み、/data/anr の直接読み取りです。

自分の端末では出力が違って見えるのはなぜ?

Android のバージョンか、メーカーのどちらかです。一部のフラグやフィールドは特定のリリースから入ったもので、それはコマンドごとに注記しています。残りはメーカーによる改変で、いちばん影響が大きいのは dumpsys です。ダンプはデバッグ出力で、そのテキストはサービスの作者が最後に印字した内容そのもの、しかもメーカーはそれを変えて自分の変更をバックポートします。フィールドは位置ではなく名前で読み、見慣れない形は失敗ではなく差分として扱ってください。

端末ではなくブラウザから実行できますか?

多くのコマンドは可能です。このサイトの Web ADB ツール群は、Chromium 系のデスクトップブラウザから WebUSB で端末と話し、SDK のインストールも不要、どこにもアップロードしません。各ページは、該当するツールがあればそこへリンクしています。知っておく価値のある制限が 2 つあります。ADB インターフェイスを保持できるプログラムは同時に 1 つだけなので、デスクトップの adb server は先に止める必要があります。そして adb forward と adb reverse はブラウザでは一切動きません。

打つより押したい場合は、Web ADB Toolkit がこの種のコマンドをブラウザから USB 経由で実行します。あるいは全コマンドを見る。