[英]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.