Run-asを使用してADBシェルからファイルをコピーするスクリプトを作成する方法はありますか?
私が知っているadbシェルにコピーする唯一の方法は、cat source > dest
を使用することです(編集:modern Androidバージョンにはcp
コマンドがあるため、この質問は不要です) 、しかし、大なり記号は1レベルの深さでしか引用できません。そのため、スクリプトはそれをadb Shellに渡すことができますが、adb Shellrun-asには渡すことができません。
たとえば、これは機能します。
adb Shell "cat source > dest"
しかし、これはしません:
adb Shell run-as "cat source > dest"
これでもない:
adb Shell "run-as cat source \> dest"
小さなスクリプトを作成してデバイスにアップロードしようとしましたが、adbシェルからスクリプトを実行できないようです。「許可が拒否されました」と表示されます。スクリプトをchmodすることもできません。
これを実行する理由は、ファイルをアプリのプライベートストレージ領域にコピーするためです。具体的には、スクリプトを使用して共有設定を変更し、変更した設定を元に戻します。ただし、アプリ自体またはルートのみが必要なファイルに書き込むことができます。
このシナリオの使用例は、ファイルを取得するのではなく、デバイス上の保護された場所にコピーすることです。取得するために、 この質問 にはすでに良い答えがあります。
OPは、次の3つのコマンド(対話型シェルセッションで次々に実行しても問題がなかった)を1つの非対話型コマンドに結合しようとしました。
adb Shell
run-as com.example.app
cat /sdcard/temp_prefs.xml > shared_prefs/com.example.app_preferences.xml
簡単にするために、インタラクティブなadb Shell
セッション内から始めましょう。最後の2つのコマンドを1行にまとめようとすると、次のようになります。
run-as com.example.app cat /sdcard/temp_prefs.xml > shared_prefs/com.example.app_preferences.xml
シェルリダイレクトがどのように機能するかにより、これは機能しません。コマンドのcat /sdcard/temp_prefs.xml
部分のみがcom.example.app
UID
で実行されます。
多くの人"know"リダイレクトに関するコマンドの一部を引用符で囲みます。
run-as com.example.app "cat /sdcard/temp_prefs.xml > shared_prefs/com.example.app_preferences.xml"
run-as
コマンドはコマンド全体を解析するほど賢くないため、これは機能しません。次のパラメータとして実行可能ファイルが必要です。それを行う適切な方法は、代わりにsh
を使用することです。
run-as com.example.app sh -c "cat /sdcard/temp_prefs.xml > shared_prefs/com.example.app_preferences.xml"
では、コマンドの前にadb Shell
を追加して、それで済ませることはできますか?必ずしも。 PCからコマンドを実行することにより、別のローカルシェルとそのパーサーも追加します。特定のエスケープ要件は、OSによって異なります。 LinuxまたはOSXでは(コマンドに'
がまだ含まれていない場合)、次のようにコマンド全体を一重引用符で囲むのは簡単です。
adb Shell 'run-as com.example.app sh -c "cat /sdcard/temp_prefs.xml > shared_prefs/com.example.app_preferences.xml"'
ただし、引用符(-out以下)を使用した代替ソリューションを使用する方が簡単な場合もあります。
adb Shell run-as com.example.app cp /sdcard/temp_prefs.xml shared_prefs/com.example.app_preferences.xml
または、デバイスにcp
コマンドがない場合:
adb Shell run-as com.example.app dd if=/sdcard/temp_prefs.xml of=shared_prefs/com.example.app_preferences.xml
また、完全なshared_prefs/com.example.app_preferences.xml
ではなく/data/data/com.example.app/shared_prefs/com.example.app_preferences.xml
を使用した方法にも注目してください。通常はrun-as
コマンド内で、現在のディレクトリはパッケージのHOME
ディレクトリです。
Chris Strattonのアドバイスに従って、私が最終的にこれを機能させる方法は次のとおりでした(共有設定をデバイスにコピーして戻すため)。
adb Push shared_prefs.xml /sdcard/temp_prefs.xml
cat <<EOF | adb Shell
run-as com.example.app
cat /sdcard/temp_prefs.xml > /data/data/com.example.app/shared_prefs/com.example.app_preferences.xml
exit
exit
EOF
adb Shell run-as
に直接配管することはできませんでした。理由はわかりませんが、adb Shell
に直接配管することはできます。秘訣は、インタラクティブシェルからrun-asを呼び出すことであり、パイプからの入力を引き続き受け入れます。
ヒアドキュメントを使用すると、コマンドを区切るために改行を簡単に埋め込むことができ、一般的には読みやすくなります。セミコロンはあまり運がなかったのですが、それは自分のやり方のせいかもしれません。複数のコマンド/改行をパイプする他の方法で機能する可能性があると思います。ようやく動作するようになったら、実験を中止しました。
シェルがぶら下がるのを防ぐために、2つの出口が必要です(CTRL-Cで殺すことができます)。 1つはrun-as
用で、もう1つはadb Shell
自体用です。 Adbのシェルはファイルの終わりにあまりうまく反応しないようです。
ディレクトリの権限を変更してから、すべてのファイルを引き出すことができます。しかし、私にとっては、共有設定ファイルを1つだけ探していたので、次のようなデータを取得できました。
PACKAGE='com.mypackage.cool'
SHAREDPREF_FILE="${PACKAGE}_preferences.xml"
adb Shell "run-as $PACKAGE cat /data/data/$PACKAGE/shared_prefs/$SHAREDPREF_FILE">$SHAREDPREF_FILE
これで、共有設定ファイルのデータが同じ名前のファイルに保存されました。