You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Python脚本向adb shell执行的进程传入输入内容?

问题根因
  • 初始化subprocess.Popen时未配置stdin=subprocess.PIPE,没有建立向子进程写入数据的通道,根本无法传入输入内容。
  • 默认执行adb shell时会为Android侧进程分配伪终端,加上默认的块缓冲机制,写入的输入如果不做特殊处理不会被即时推送到目标进程,表现为进程卡住无响应。
  • 传入字符串命令+shell=True的写法会额外嵌套一层本地shell进程,输入输出链路多一层转发,很容易出现阻塞、缓冲不刷新的问题。
可直接运行的修复代码
import subprocess

# 命令用列表形式传递,禁用shell=True减少中间转发层,-T参数关闭adb的tty分配,解决缓冲卡住问题
cmd = ["adb", "shell", "-T", "libtest_ip"]
p = subprocess.Popen(
    cmd,
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    text=True  # Python3.7+支持,自动处理编解码,无需手动转bytes
)

# 传入输入,每个输入项末尾必须加\n,模拟终端回车提交操作
input_data = "1\nen_us\n"
# communicate会一次性把输入写入进程,等待进程执行完成后返回所有输出
stdout, stderr = p.communicate(input=input_data, timeout=15)

print("程序标准输出:\n", stdout)
print("程序错误输出:\n", stderr)
交互式场景适配

如果libtest_ip是动态交互逻辑,需要根据上一步输出决定下一次输入,不要用communicate()(该方法会等待进程结束才返回),直接操作stdin管道即可,注意写完必须强制刷新缓冲:

import time

# 写入第一个输入
p.stdin.write("1\n")
p.stdin.flush()
# 按需等待程序处理,也可以读p.stdout的内容判断处理进度
time.sleep(0.3)
# 写入第二个输入
p.stdin.write("en_us\n")
p.stdin.flush()

# 执行完成后回收资源
p.stdin.close()
return_code = p.wait()
额外注意事项
  • 如果加了-T参数还是存在缓冲卡住的问题,可以把命令换成["adb", "exec-out", "libtest_ip"],exec-out不会经过Android侧的shell中转,直接执行二进制文件,输入输出链路更短,缓冲问题更少。
  • 开启stdout/stderr管道后,不要持续写入stdin却不读取输出,管道缓冲区占满后会触发死锁。如果不需要捕获输出,可以把stdout/stderr参数设为subprocess.DEVNULL。
  • 所有传给进程的输入内容末尾必须加换行符,否则程序会认为输入还没提交,一直等待回车。

内容的提问来源于stack exchange,提问作者user1658384

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.15 16:16:02