使用run-as在ADB shell中复制文件

时间:2014-03-28 02:45:42

标签: android shell adb

有没有办法编写一个脚本,使用run-as?

从ADB shell复制文件

我知道在adb shell中复制的唯一方法是使用cat source > dest(编辑:现代android版本有cp命令,这使得这个问题变得不必要了),但我只能引用一个级别的大于号的符号 - 所以我的脚本可以将它传递给adb shell,但不能传递给adb shell run-as。

例如,这有效:

adb shell "cat source > dest"

但这不是:

adb shell run-as "cat source > dest"

也不是这样:

adb shell "run-as cat source \> dest"

我甚至尝试创建一个小脚本并将其上传到设备,但我似乎无法从adb shell运行脚本 - 它告诉我“权限被拒绝”。我也不能chmod脚本。

我想这样做的原因是将文件复制到应用程序的私有存储区域 - 具体来说,我使用脚本来修改共享首选项并将修改后的首选项放回原处。但是,只有应用程序本身或root可以写入我想要的文件。

此方案中的用例是将文件复制到设备上的受保护位置,而不是检索它;对于检索,this question已经有了很好的答案。

3 个答案:

答案 0 :(得分:12)

按照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。诀窍是然后从交互式shell调用run-as,它继续接受来自管道的输入。

HERE doc让我可以轻松地将换行符嵌入到单独的命令中,通常只是让它可读;我用分号没有太多运气,但那可能是因为我做事的方式。我相信它可能适用于管道多个命令/换行符的其他方法;一旦我终于开始工作,我就停止了实验。

这两个出口是防止悬挂壳体所必需的(可以用CTRL-C摇动);一个用于run-as,另一个用于adb shell本身。看起来,Adb的shell并没有很好地响应文件结尾。

答案 1 :(得分:4)

OP尝试将以下3个命令(在交互式shell会话中一个接一个地执行)没有问题组合成一个非交互式命令:

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

为简单起见,我们从交互式adb shell会话开始。如果我们只是尝试将最后两个命令组合成一行:

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

由于shell重定向的工作原理,这不起作用 - 只有命令的cat /sdcard/temp_prefs.xml部分才能与com.example.app UID一起运行

许多人“知道”将命令的一部分重定向到引号:

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运行命令,您还可以添加另一个本地shell及其解析器。具体的逃生要求取决于您的操作系统。在Linux或OSX中(如果您的命令尚未包含任何'),很容易单引引整个命令,如下所示:

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

但有时使用带有( - 或更少)引号的替代解决方案更容易:

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目录。

答案 2 :(得分:2)

您只需更改目录的权限,然后将所有文件拉出。但对我来说,我只是寻找一个共享偏好文件,我能够得到这样的数据:

PACKAGE='com.mypackage.cool'
SHAREDPREF_FILE="${PACKAGE}_preferences.xml"

    adb shell "run-as $PACKAGE cat /data/data/$PACKAGE/shared_prefs/$SHAREDPREF_FILE">$SHAREDPREF_FILE

现在我们将sharedpreference文件的数据存储在同名文件中。