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
相关产品推荐
相关产品推荐

