web-dev-qa-db-ja.com

run-asを使用してADBシェルでファイルをコピーする

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することもできません。

これを実行する理由は、ファイルをアプリのプライベートストレージ領域にコピーするためです。具体的には、スクリプトを使用して共有設定を変更し、変更した設定を元に戻します。ただし、アプリ自体またはルートのみが必要なファイルに書き込むことができます。

このシナリオの使用例は、ファイルを取得するのではなく、デバイス上の保護された場所にコピーすることです。取得するために、 この質問 にはすでに良い答えがあります。

7
Logan Pickup

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.appUIDで実行されます。

多くの人"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ディレクトリです。

8
Alex P.

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のシェルはファイルの終わりにあまりうまく反応しないようです。

12
Logan Pickup

ディレクトリの権限を変更してから、すべてのファイルを引き出すことができます。しかし、私にとっては、共有設定ファイルを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

これで、共有設定ファイルのデータが同じ名前のファイルに保存されました。

3
j2emanue