Android 使用 run-as 在 ADB shell 中复制文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22703254/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Copying files in ADB shell with run-as
提问by Logan Pickup
Is there a way to write a script that will copy files from an ADB shell using run-as?
有没有办法编写一个脚本来使用 run-as 从 ADB shell 复制文件?
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.
我知道在 adb shell 中复制的唯一方法是使用cat source > dest
(编辑:现代 android 版本有cp
命令,这使得这个问题变得不必要),但我只能引用大于号一级深 - 所以我的脚本可以将其传递给 adb shell,但不能传递给 adb shell run-as。
For example, this works:
例如,这有效:
adb shell "cat source > dest"
adb shell "cat source > dest"
But this does not:
但这不会:
adb shell run-as "cat source > dest"
adb shell run-as "cat source > dest"
Nor this:
也不是这个:
adb shell "run-as cat source \> dest"
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.
我什至尝试创建一个小脚本并将其上传到设备,但我似乎无法从 adb shell 运行该脚本 - 它告诉我“权限被拒绝”。我也无法修改脚本。
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.
我想要这样做的原因是将文件复制到应用程序的私有存储区域 - 具体来说,我正在使用脚本来修改共享首选项并将修改后的首选项放回原处。但是,只有应用程序本身或 root 可以写入我想要的文件。
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.
此场景中的用例是将文件复制到设备上的受保护位置,而不是检索它;为了检索,这个问题已经有很好的答案了。
回答by Logan Pickup
Following Chris Stratton's advice, the way I eventually got this to work was as follows (for copying shared preferences back to the device):
按照 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
Piping directly to adb shell run-as
did not work, and I do not know why, but piping to adb shell
does. The trick is to then call run-as from the interactive shell, and it continues to accept input from the pipe.
直接管道到adb shell run-as
不起作用,我不知道为什么,但是管道到adb shell
可以。诀窍是然后从交互式 shell 调用 run-as,它继续接受来自管道的输入。
The HERE doc lets me easily embed the newlines to separate commands and in general just makes it readable; I did not have much luck with semicolons, but that might have been because of the way I was doing things. I believe it might work with other methods of piping multiple commands/newlines; I stopped the experiment once I finally got it to work.
HERE 文档让我可以轻松地将换行符嵌入到单独的命令中,并且通常只是使其可读;我对分号不太走运,但这可能是因为我做事的方式。我相信它可能适用于管道多个命令/换行符的其他方法;一旦我终于让它工作,我就停止了实验。
The two exits are necessary to prevent a hanging shell (killable with CTRL-C); one for run-as
, and the other for adb shell
itself. Adb's shell doesn't respond to end-of-file very nicely, it seems.
这两个出口对于防止挂起的 shell 是必要的(可以用 CTRL-C 杀死);一个为run-as
,另一个为adb shell
自己。Adb 的 shell 似乎没有很好地响应文件结尾。
回答by Alex P.
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:
OP 尝试将以下 3 个命令(他在交互式 shell 会话中一个接一个执行没有问题)合并为一个非交互式命令:
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:
为简单起见,让我们从交互式adb shell
会话中开始。如果我们只是尝试将最后两个命令合并为一行:
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
由于 shell 重定向的工作方式,这将不起作用 - 只有cat /sdcard/temp_prefs.xml
命令的一部分将与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
命令不够智能,无法解析整个命令。它期望一个可执行文件作为下一个参数。正确的做法是sh
改用:
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
可以在命令的前面加上它吗?不必要。通过从您的 PC 运行命令,您还可以添加另一个本地 shell 及其解析器。具体的转义要求取决于您的操作系统。在 Linux 或 OSX 中(如果您的命令还没有包含任何'
),很容易像这样用单引号引用整个命令:
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:
但有时使用带有(-out 或更少)引号的替代解决方案更容易:
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:
或者,如果您的设备没有以下cp
命令:
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.
还要注意我如何使用shared_prefs/com.example.app_preferences.xml
而不是 full /data/data/com.example.app/shared_prefs/com.example.app_preferences.xml
- 通常在run-as
命令内部,您的当前目录是HOME
您的包的目录。
回答by j2emanue
you could just change the permission of the directory and then pull all the files out. but for me i was looking for just one shared preference file and i was able to get the data like this:
您可以更改目录的权限,然后将所有文件拉出。但对我来说,我只是在寻找一个共享首选项文件,我能够获得这样的数据:
PACKAGE='com.mypackage.cool'
SHAREDPREF_FILE="${PACKAGE}_preferences.xml"
adb shell "run-as $PACKAGE cat /data/data/$PACKAGE/shared_prefs/$SHAREDPREF_FILE">$SHAREDPREF_FILE
now we have the data of the sharedpreference file stored in a file of the same name.
现在我们将共享首选项文件的数据存储在同名文件中。