繁体   English   中英

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

[英]Copying files in ADB shell with run-as

有没有办法编写一个脚本,使用 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 可以写入我想要的文件。

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

遵循克里斯·斯特拉顿的建议,我最终使它起作用的方式如下(用于将共享首选项复制回设备):

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可以。 诀窍是,然后从交互式外壳程序调用运行方式,并继续接受来自管道的输入。

这里的文档使我可以轻松地将换行符嵌入到单独的命令中,并且通常使它易于阅读; 我在分号方面运气不太好,但这可能是因为我做事的方式。 我相信它可以与传递多个命令/换行符的其他方法一起使用; 终于让实验开始工作后,我就停止了实验。

这两个出口对于防止挂壳是必需的(可通过CTRL-C杀死); 一个用于run-as ,另一个用于adb shell本身。 看来,Adb的外壳对文件结束的响应不是很好。

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

您可以只更改目录的权限,然后拉出所有文件。 但是对我来说,我只在寻找一个共享的首选项文件,并且我能够获得像这样的数据:

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文件的数据存储在同名文件中。

使用最新的adb (ADB v1.0.41 / 版本 33.0.3)和 Play Store 模拟器图像,我遇到了adb root未被授予的情况。 我也无法从/data/local//storage/emulated/0/复制,因为在run-as com.myapp.app时没有权限

new_prefs_path="my_machine.xml"
config="$(cat $new_prefs_path)"
my_app_uri="com.myapp.app"
adb shell "run-as $my_app_uri sh -c 'echo \"$config\" > shared_prefs/on_android.xml'"

这为我将其修复为 bash 脚本。 由于需要为不同的应用程序和复杂的有效负载进行配置,它变得稍微复杂一些。 我们获取一个文件(可以在此脚本的前面生成)并将其读取到一个变量中。 然后我们启动 shell,执行run-as my app 并运行 echo 将读取的文件扩展到 shared_prefs 中的文件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM