Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
386 views
in Technique[技术] by (71.8m points)

android - Copying files in ADB shell with run-as

Is there a way to write a script that will copy files from an ADB shell using run-as?

The only way I know of to copy in the adb shell is using cat source > dest (edit: modern android versions have the cp command, which makes this question unnecessary), but I am only able to quote the greater-than sign one level deep - so my script can pass it to adb shell, but not to adb shell run-as.

For example, this works:

adb shell "cat source > dest"

But this does not:

adb shell run-as "cat source > dest"

Nor this:

adb shell "run-as cat source > dest"

I even tried created a small script and uploading it to the device, but I can't seem to run the script from the adb shell - it tells me "permission denied". I can't chmod the script, either.

The reason I want to do this is to copy a file into an app's private storage area - specifically, I am using a script to modify shared preferences and put the modified preferences back. Only the app itself or root can write to the file I want, however.

The use case in this scenario is coping a file to a protected location on the device, not retrieving it; for retrieving, there are already good answers in this question.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The OP tried to combine the following 3 commands (that he had no problem executing one after another in the interactive shell session) into a single non-interactive command:

adb shell
run-as com.example.app
cat /sdcard/temp_prefs.xml > shared_prefs/com.example.app_preferences.xml

For simplicity let's start from within an interactive adb shell session. If we just try to combine the last two commands into a single line:

run-as com.example.app cat /sdcard/temp_prefs.xml > shared_prefs/com.example.app_preferences.xml

This would not work because of how shell redirection works - only the cat /sdcard/temp_prefs.xml part of the command would be run with com.example.app UID

Many people "know" to put the part of the command around redirection into quotes:

run-as com.example.app "cat /sdcard/temp_prefs.xml > shared_prefs/com.example.app_preferences.xml"

This does not work because the run-as command is not smart enough to parse the whole command. It expects an executable as the next parameter. The proper way to do it would be to use sh instead:

run-as com.example.app sh -c "cat /sdcard/temp_prefs.xml > shared_prefs/com.example.app_preferences.xml"

So can we just prepend adb shell to the command and be done with it? Not necessarily. By running the command from your PC you also add another local shell and its parser. Specific escape requirements would depend on your OS. In Linux or OSX (if your command does not already contain any ') it is easy to single-quote the whole command like so:

adb shell 'run-as com.example.app sh -c "cat /sdcard/temp_prefs.xml > shared_prefs/com.example.app_preferences.xml"'

But sometimes it is just easier to use an alternative solutions with (-out or less) quotes:

adb shell run-as com.example.app cp /sdcard/temp_prefs.xml shared_prefs/com.example.app_preferences.xml

Or if your device does not have the cp command:

adb shell run-as com.example.app dd if=/sdcard/temp_prefs.xml of=shared_prefs/com.example.app_preferences.xml

Also notice how I used shared_prefs/com.example.app_preferences.xml instead of full /data/data/com.example.app/shared_prefs/com.example.app_preferences.xml - normally inside of run-as command your current directory is the HOME dir of your package.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.9k users

...