如何直接从我的应用程序向ADB shell发送命令?

时间:2015-03-19 11:50:45

标签: windows shell python-3.x adb popen

我想在ADB shell中发送命令,就像我在cmd中完成了以下操作一样。

    >adb shell
    shell@:/ <command>

我在Windows 7 OS 64bit机器上使用python 3.4。我只需使用subprocess.getoutput发送单行shell命令,例如:

subprocess.getoutput ('adb pull /storage/sdcard0/file.txt')

只要adb命令本身被ADB特别识别,例如pull和push,但是还有其他命令如grep需要在shell中运行,如上所述,因为它们不被adb识别。例如,以下行不起作用:

subprocess.getoutput ('adb shell ls -l | grep ...')

要在shell中输入命令,我认为我需要某种期望的库,因为这就是每个人&#39;但是,无论如何,我们都会看到,并且看起来并且葡萄酒都无法发挥作用。它们是为python 2编写的,在被移植到python 3之后,我手工浏览.py文件,即使是那些经过调整的窗口,也没有任何工作 - 每个都是出于不同的原因。

如何将我想要的输入直接发送到adb shell?

2 个答案:

答案 0 :(得分:0)

如果已经推荐的快捷方式都不适合您,您仍然可以去常规快捷方式。使用&#39; subprocess.Popen&#39;使用Popen在

    cmd1 = 'adb shell'
    cmd2 = 'ls -l | grep ...'
    p = subprocess.Popen(cmd1.split(), stdin=PIPE)
    time.sleep(1)
    p.stdin.write(cmd2.encode('utf-8'))
    p.stdin.write('\n'.encode('utf-8'))
    p.stdin.flush()
    time.sleep(3)
    p.kill()

要记住一些事情:

  1. 即使你导入子进程,你仍然需要调用subprocess.Popen
  2. 将cmd1作为字符串或列表中的项目发送也应该有效但是&#39; .split()&#39;诀窍并且在眼睛上更容易
  3. 因为您只是指定要输入shell的输入,所以只需要stdin = PIPE。只有当你想从shell接收输出时才需要stdout
  4. time.sleep(1)并不是必需的,但是因为许多人抱怨输入问题在python 2中比较快或者慢3考虑可能使用它。 &#39;他们&#39;可能一直在使用&#39; expect&#39;首先需要shell的回复。这个代码也可以工作,当我测试它只需交换和在过程中time.sleep(0)
  5. 如果输入编码不正确,
  6. stdin.write将返回错误。 python的默认值是unicode。在我的测试中,通过二进制输入对我来说不起作用,这样&#34; b \ ls ...&#34;但.encode()有效。别忘了结束!
  7. 如果您使用.encode(),则担心该行可能无法正常发送,因此请确保包含flush()可能更好。
  8. time.sleep(3)是完全不可取的,但是如果你的命令需要很长时间才能执行(例如,通过整个设备的回归搜索传输到存储卡上的txt文件)可能会给它一些额外的时间杀死任何人。
  9. 记得杀人。如果你没有杀死它,管道可能会保持打开状态,即使退出控制台上的测试应用程序,下一个命令仍然会转到shell,即使提示似乎是我的常规cmd提示。

答案 1 :(得分:0)

Amichai,我必须首先指出你自己的&#34;解决方案&#34;太可怕了。你的解释使情况变得更糟。只是因为你不理解shell(这里我的意思是你的PC的操作系统shell,而不是adb)命令解析,所以做了所有这些不必要的事情。

当你需要的只是这一个命令时:

subprocess.check_output(['adb', 'shell', 'ls /storage/sdcard0 | grep ...']).decode('utf-8')