Python实现ADB Shell交互遇问题,求可行解决方案
解决ADB Shell交互式Python脚本问题
问题根源分析
- 命令格式错误:当
shell=False时,Popen需要将命令和参数拆分为列表形式,而非单个字符串。原代码中'adb shell'会被当作一个完整的可执行文件名,系统无法找到,导致进程启动失败。 - 读取阻塞:
p.stdout.read()会一直等待进程输出EOF才返回,但交互式adb shell不会主动发送EOF,导致代码卡住,后续写入命令的逻辑无法执行。 - 命令未触发执行:发送给
adb shell的命令需要以换行符结尾(模拟回车),否则命令不会被执行。
解决方案1:持续交互式操作
如果需要保持adb shell连接并执行多条命令,可按以下方式编写代码:
from subprocess import Popen, PIPE # 正确启动adb shell进程:shell=False时用列表传参 p = Popen(['adb', 'shell'], stdin=PIPE, stdout=PIPE, stderr=PIPE, universal_newlines=True) # 发送第一条命令:切换目录,注意加换行符 p.stdin.write("cd /data/app\n") p.stdin.flush() # 发送第二条命令:启动应用(替换为你的包名和Activity) p.stdin.write("am start -n com.example.app/.MainActivity\n") p.stdin.flush() # 读取输出(逐行读取避免阻塞) while True: line = p.stdout.readline() if not line: break print(line.strip()) # 关闭进程 p.stdin.close() p.wait()
解决方案2:单命令直接执行(更简单)
如果不需要持续交互,只是执行单条或多条串联命令,可直接通过adb shell <command>的方式调用,避免处理交互式进程的阻塞问题:
from subprocess import check_output, CalledProcessError # 执行ls -l命令 try: output = check_output(['adb', 'shell', 'ls -l'], universal_newlines=True) print(output) except CalledProcessError as e: print(f"命令执行失败: {e}") # 切换目录并启动应用(用分号串联命令) try: output = check_output(['adb', 'shell', 'cd /data/app && am start -n com.example.app/.MainActivity'], universal_newlines=True) print(output) except CalledProcessError as e: print(f"启动应用失败: {e}")
关于shell=True的问题
设置shell=True时,Windows系统会启动cmd.exe来解析命令,所以会弹出cmd窗口。保持shell=False并使用列表传参的方式,即可避免弹出窗口,同时保证进程正常启动。
内容的提问来源于stack exchange,提问作者Mischa M
相关产品推荐
相关产品推荐

