【问题标题】:How to open adb shell and execute commands inside shell using python如何使用python打开adb shell并在shell中执行命令
【发布时间】:2016-07-21 05:20:29
【问题描述】:

我正在尝试使用 subprocess.Popen 在 python 中执行 adb shell 命令

示例:需要在 adb shell 中执行“命令”。手动执行时,我打开命令窗口并如下执行,它可以工作。

>adb shell
#<command>

在 Python 中我使用如下,但进程卡住并且没有输出

subprocess.Popen('adb shell <command>)

尝试在命令窗口手动执行,结果和python代码一样,卡住了,没有输出

>adb shell <command>

我正在尝试在命令中在后台执行一个二进制文件(使用二进制文件名后跟 &)。

【问题讨论】:

    标签: android python shell adb


    【解决方案1】:

    在子进程模块中找到了一种使用communicate()方法的方法

    procId = subprocess.Popen('adb shell', stdin = subprocess.PIPE)
    procId.communicate('command1\ncommand2\nexit\n')
    

    【讨论】:

    • 我不知道它为什么起作用,但它不再起作用了。现在只有这些命令有效。 cmd = ['adb', 'shell'] procId = subprocess.Popen(cmd, stdin=subprocess.PIPE) 而且我必须指出 procId.communicate('command1\ncommand2\nexit\n') 在 Python3 中不起作用,因为抛出了这个异常:TypeError: a bytes-like object is required, not 'str'。请改用此命令:procId.communicate(b'command1\ncommand2\nexit\n')(在字符串前加上“b”),因为它在 Python2 和 Python3 中都有效。
    【解决方案2】:

    Ankur Kabra,试试下面的代码:

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    import subprocess
    command = 'adb devices'
    p = subprocess.Popen(command, shell=True,
                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout, stderr = p.communicate()
    print 'standard output: %s \n error output: %s \n',(stdout,stderr)
    

    你会看到错误输出。

    通常它会告诉你:

     /bin/sh: adb: command not found
    

    这意味着,shell 不能执行adb 命令。 因此,将adb 添加到您的PATH 或编写adb 的完整路径将解决问题。

    可能会有所帮助。

    【讨论】:

    • 嗨,我试过上面的代码。我没有错误。输出是设备列表。我想使用 python 打开 adb shell,然后再次使用 python 在该 shell 中执行命令。 subprocess.Popen('adb shell')->这会按预期打开 shell。接下来我想在这个 shell 中执行语句。我该怎么做?
    • 嗨,如果您想使用 python 打开 adb shell,然后再次使用 python 在该 shell 中执行命令,请使用 subprocess.Popen('adb shell shell_command')。您不必进行长连接,每次执行shell命令时连接到shell即可。
    • 是的,它通常可以工作,但我的命令似乎有一些问题。如果我在一行中给出它,则没有输出。
    • subprocess.Popen('adb shell setenforce 0')---->works subprocess.Popen('adb shell webserver &')----->程序卡在这一步。这里的网络服务器是二进制文件
    • 首先,检查webserver二进制文件是否在您的手机存储中。其次,试试adb shell,然后运行webserver 来检查你是否有文件的执行权限。
    【解决方案3】:

    使用 pexpect (https://pexpect.readthedocs.io/en/stable/)

    adb="/Users/lishaokai/Library/Android/sdk/platform-tools/adb"
    import pexpect
    import sys, os
    child = pexpect.spawn(adb + " shell")
    child.logfile_send = sys.stdout
    
    while True:
      index = child.expect(["$","@",pexpect.TIMEOUT])
      print index
      child.sendline("ls /storage/emulated/0/")
      index = child.expect(["huoshan","google",pexpect.TIMEOUT])
      print index, child.before, child.after
      break
    

    【讨论】:

    • 得到错误 child = pexpect.spawn(adb + "shell") AttributeError: 'module' object has no attribute 'spawn'
    • easy_install pexpect 安装这个包
    • 我使用的是python2.7。使用 pip install pexpect 安装。但似乎模块生成不存在。
    • 在命令行模式下,import pexpect;help(pexpect) 看看你到底在安装什么
    最近更新 更多