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

Python Popen执行adb命令Linux正常Windows运行报错解决方法

问题根因

异常来自不同操作系统默认shell的引号解析规则差异,和Python本身、adb版本无关:

  • Linux下执行带shell=True的subprocess调用时,默认使用sh/bash解析命令,单引号会被识别为参数边界,不会作为命令内容传递。最终传入安卓侧/system/bin/sh的是完整可执行的find /data/ -type f ! -empty命令,可正常运行。
  • Windows下默认使用cmd.exe/PowerShell解析命令,二者均不将单引号识别为参数包裹符,单引号会被当作普通字符随命令内容一起传递给adb。最终安卓侧shell收到的是带冗余符号的错误命令,自然会提示找不到对应可执行文件。
跨平台兼容修复方案

最稳妥的修复方式是彻底绕开系统shell的解析逻辑:给subprocess传入拆分好的命令参数列表,同时关闭shell=True选项,从根源上消除不同系统shell的语法差异,不需要额外做系统判断即可同时兼容Linux、Windows、macOS。
修复后的完整代码如下:

#!/usr/bin/env python3
import subprocess
import sys

def runcmd(cmd, show=True):
    cmd_str = cmd if isinstance(cmd, str) else " ".join(cmd)
    print(f"cmd:{cmd_str}")
    try:
        p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        retval = p.communicate()[0]
        print(retval)
        # 自动适配系统默认编码,避免不同环境下解码报错
        return retval.decode(sys.stdout.encoding, errors="ignore")
    except Exception as e:
        print(f"cmd error:{cmd_str}, err_info:{e}")
        return ""

def main():
    # 命令拆分为参数列表传递,不需要额外加引号包裹
    runcmd(["adb", "shell", "find", "/data/", "-type", "f", "!", "-empty"])
    return

if __name__ == "__main__":
    main()

额外说明

如果一定要保留字符串形式传命令的写法,需要额外判断当前运行系统:Windows下把命令里的单引号替换为双引号,Linux下保留单引号即可。但这种写法维护成本高,不推荐使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 00:47:07