首页 > 解决方案 > 'adb shell' 这两个壳是链式的吗?

问题描述

行为的某些方面adb shell ...表明,这是两个shell,它们链接了该命令背后的东西。adb shell这意味着调用序列的主机的一个 shell ,然后是目标系统 shell。命令字符串似乎通过两个 shell 的管道。

adb -s $AdbID shell echo find  / -type f \( -name \*audio\* -or \
  -name \*alsa\* \) \( -path /usr/lib/\* -or -path /usr/bin/\* -or \
  -path /etc/\*  \)

结果是:

find / -type f ( -name *audio* -or -name *alsa* ) \
    ( -path /usr/lib/busybox /usr/lib/dbus /usr/lib/faketime /usr.... long list of matching file system items follows )

扩展模式的项目列表显示扩展发生在目标设备文件系统中,而不是在adb shell被调用的主机上。这意味着主机上没有发生全局扩展。这是由于转义星号。看起来主机外壳消耗了星号转义字符并且很满意。未转义的星号然后转到目标设备外壳,在那里它们被用于 glob 扩展。我自己尝试了许多其他方法来逃避 -path 模式中的星号。对于所有这些,结果与上述相同。

对于 Bash,引号的删除是在所有其他类型的扩展之后进行的。不知道它对 adb 目标上的 shell 是如何工作的。

但是为什么命令分组 - 括号 - 不显示二元性?分组逃逸被消耗,无论如何分组被传递到目标命令“查找”,就像它是一个单一的外壳一样。这一观察结果与上述论点背道而驰。

作为关于输入命名 A.. D.. Bridge (adb) 的论文的另一个支持论点,似乎有很好的理由 - 在这种情况下,这块软件充当了两个 shell 之间的桥梁。

如果 adb shell one 处理两个 shell 的链,真的是这样吗?否则如何解释所做的观察?它可能是 adb shell 或目标 shell 的错误吗?

注意:这里的 Busybox 在目标系统上运行。

标签: shellescapingadbquotesglob

解决方案


是的,有两个 shell:本地 shell 和远程 shell。

adb shell使用system(3)语义,就像sshand一样eval。使用这种约定,所有参数都用空格连接,然后由 shell 评估。

另一种选择是execve(2)语义,由sudoand使用xargs。按照这种约定,第一个参数被认为是可执行文件名,其余的作为参数逐字传递。这是您要尝试做的事情,通常最好是因为它安全且健壮,但adb shell不支持它。

adb shell使用任意命令运行,您必须为远程 shell 转义适当的值,然后转义整个命令,以便本地 shell 正确传递它。

在这种情况下,您可以简单地将转义的命令用单引号括起来:

adb shell 'echo find  / -type f \( -name \*audio\* -or \
  -name \*alsa\* \) \( -path /usr/lib/\* -or -path /usr/bin/\* -or \
  -path /etc/\*  \)'

不过,我无法用括号解释您所说的内容。他们肯定应该给出一个错误,他们为我做了:

$ adb shell echo find / -type f \( -name ...
/system/bin/sh: syntax error: '(' unexpected

推荐阅读