【问题标题】:Copying files in ADB shell with run-as使用 run-as 在 ADB shell 中复制文件
【发布时间】:2014-05-07 08:23:23
【问题描述】:

有没有办法编写一个脚本来使用 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 运行脚本 - 它告诉我“权限被拒绝”。我也不能修改脚本。

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

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

【问题讨论】:

  • 您可能无法执行上传的脚本,因为外部存储是使用 noexec 标志安装的。如果您将它放在应用程序的私有存储或 /data 下的某个 tmp 目录中,您应该能够使其可执行。但是,如何将导出功能构建到应用程序的(调试版本)中,以这种方式进行复制?另一种选择是将来自echo 之类的命令管道adb shell run-as com.foo.bar 会话中。
  • 是否可以使用 adb 将脚本复制到应用程序的私有存储中?我总是被拒绝许可,如果我可以推送到应用程序的私人存储,那么我就不会遇到这个问题。不过,我会尝试从 echo 中进行管道传输。
  • 您可以让应用程序写出脚本或授予您对目录的写入权限。
  • 顺便说一句,如果您使用的是最新版本,Android 现在有一个cp 命令。
  • 我一直在寻找没有应用程序帮助的东西,因为我有很多沙箱,我会定期与版本控制同步,而且有很多人在做这个项目;尽管我可以对应用程序进行临时更改,但它们可能只会持续到下次我在进行还原时忘记更改时。这就是为什么让脚本做所有事情会很好的原因。不幸的是,我用来拥有 cp 的手机上没有足够新的版本。顺便说一句,谢谢你的帮助!

标签: android shell adb


【解决方案1】:

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"'

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

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】:

    按照 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 文档让我可以轻松地将换行符嵌入到单独的命令中,并且通常只是使其可读;我对分号不太走运,但这可能是因为我做事的方式。我相信它可能适用于管道多个命令/换行符的其他方法;一旦我终于开始工作,我就停止了实验。

    两个出口对于防止挂起的 shell 是必要的(可以用 CTRL-C 杀死);一个用于run-as,另一个用于adb shell 本身。似乎 Adb 的 shell 对文件结尾的响应不是很好。

    【讨论】:

    • 很好地弄清楚如何使它工作。我的错误是试图通过管道输入adb shell run-as,这显然表现不同。
    • @ChrisStratton 我一开始也是这样尝试的。直到我发现它通过adb shellfine 之后我才想到这样做。
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-17
      • 1970-01-01
      • 2014-11-06
      • 1970-01-01
      相关资源
      最近更新 更多