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

subprocess.run()调用shell脚本无预期输出问题求解

问题根因

你的代码存在几个直接导致异常的问题:

  • 语法错误:脚本路径/path/script.sh没有用引号包裹为字符串,Python解析阶段就会报语法错误,根本不会执行到子进程调用逻辑。
  • 工作目录不匹配:就算补全引号,子进程默认的工作目录是Python进程的启动目录,和你手动在终端执行脚本时所在的目录大概率不一致,你传入的相对路径text1.txt、text2.txt会找不到,cat命令执行失败。
  • 输出读取错误:你设置了capture_output=True,脚本的所有标准输出、错误输出都会被捕获存入返回对象的属性中,直接print(sp.run(...))只会打印CompletedProcess对象的结构信息,不会输出脚本实际执行的拼接结果;同时check=True会在脚本执行失败时直接抛出异常,错误信息里才会包含找不到文件的提示,你之前没捕获异常也没打印stderr,就会误以为脚本没执行。
  • 前置权限问题:如果你的script.sh没有加可执行权限,调用时会直接报权限拒绝错误。
正确写法

优先用参数列表传参的方式,不要拼接shell命令,避免命令注入风险,同时显式指定工作目录:

import subprocess as sp

# 先在终端执行 chmod +x /path/script.sh 给脚本加可执行权限
res = sp.run(
    # 命令和参数分开传,不要自己拼接字符串
    ["/path/script.sh", "text1.txt", "text2.txt"],
    check=True,
    text=True,
    capture_output=True,
    # 替换成你手动在终端执行脚本时,text1.txt/text2.txt所在的绝对路径
    cwd="/home/yourname/your_work_dir"
)
# 打印脚本实际输出的拼接内容
print(res.stdout)
# 如果执行有问题,先打印stderr看报错
# print(res.stderr)

如果你一定要用shell=True的模式,写法如下,同样需要指定工作目录:

import subprocess as sp

res = sp.run(
    "/path/script.sh text1.txt text2.txt",
    shell=True,
    check=True,
    text=True,
    capture_output=True,
    cwd="/home/yourname/your_work_dir"
)
print(res.stdout)

调试提示:如果还是不符合预期,先把capture_output=True暂时去掉,让子进程的输出直接打印到控制台,能第一时间看到是路径错误、权限错误还是参数传错。

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

相关产品推荐
方舟 Agent Plan

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

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