subprocess:把参数列表交给进程,不拼接 shell 文本
用户输入中出现空格、引号或特殊符号时,拼接命令字符串容易改变命令含义。直接传参数列表能保留各参数的边界。
问题从哪里出现
用户输入中出现空格、引号或特殊符号时,拼接命令字符串容易改变命令含义。直接传参数列表能保留各参数的边界。
理解核心机制
subprocess.run 默认不通过 shell。check=True 把非零退出状态变成异常,timeout 限制等待,capture_output 与 text 方便处理文本结果。
动手做一个小实验
Python 3.11 或更新版本,仅使用标准库;将示例保存为 demo.py 后执行 python3 demo.py。
import subprocess
import sys
result = subprocess.run(
[sys.executable, "-c", "import sys; print(sys.argv[1])", "hello world; literal"],
check=True, capture_output=True, text=True, timeout=5,
)
assert result.stdout.strip() == "hello world; literal"
print(result.stdout.strip())适用边界与常见误区
不用 shell 并不能消除被调用程序自己的选项注入风险。程序路径、允许参数及输出大小仍需约束;很大输出不宜全部 capture 到内存。
继续练习
测试带空格和引号的普通参数,再让子进程非零退出,分别查看返回码、stdout 与 stderr 的处理方式。