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

使用subprocess调用带重定向的Bash脚本时的输出异常问题

问题与解决方案

原Bash脚本

#!/bin/bash

BIN_FOLDER=bin
SEQ_BIN=some_binary
PROFILE_FOLDER=profiles/
FILENAME=$1

mkdir -p $PROFILE_FOLDER

sudo perf record -g -F 999 $BIN_FOLDER/$SEQ_BIN "${@:2}"
sudo sh -c "perf script -F +pid > $PROFILE_FOLDER/$FILENAME.perf"
sudo rm perf.*

直接运行脚本的预期输出

<some_binary output>
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0,025 MB perf.data (6 samples) ]

问题描述

直接在Shell中运行上述脚本时,终端能正常输出预期内容,同时生成profiles/$FILENAME.perf文件。但通过Python的subprocess.run并设置capture_output=True调用时,捕获到的stdout结果变成了perf script命令的输出(呈现为大量乱码),无法得到和直接运行时一致的终端内容。需要在保留脚本生成文件功能的前提下解决捕获输出的问题,且最好不修改原Bash脚本。


解决方案

方法1:合并stdout与stderr,捕获终端完整输出

直接运行脚本时,终端会同时显示some_binary的标准输出(stdout)和perf record的提示信息(标准错误stderr),而perf script的输出已被脚本内的重定向写入文件,不会出现在终端。在Python中,只需将脚本的stderr合并到stdout中捕获,就能得到和终端完全一致的内容:

import subprocess

# 替换为你的脚本路径、输出文件名及参数
cmd = ["./your_script.sh", "test_profile", "arg1", "arg2"]
result = subprocess.run(
    cmd,
    stdout=subprocess.PIPE,
    stderr=subprocess.STDOUT,
    text=True
)

# 打印捕获到的内容,与直接运行脚本的终端输出一致
print(result.stdout)
# 脚本会正常生成profiles/test_profile.perf文件

方法2:单独捕获stdout和stderr,按需处理

如果需要分开处理some_binary的输出和perf record的提示信息,可以分别捕获两个流:

import subprocess

cmd = ["./your_script.sh", "test_profile", "arg1", "arg2"]
result = subprocess.run(
    cmd,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    text=True
)

# some_binary的输出内容
print("程序输出:", result.stdout)
# perf record的提示信息
print("perf记录日志:", result.stderr)

注意事项

如果脚本依赖特定工作目录才能正确生成文件,可以在调用时指定cwd参数:

result = subprocess.run(
    cmd,
    stdout=subprocess.PIPE,
    stderr=subprocess.STDOUT,
    text=True,
    cwd="/path/to/script/directory"  # 脚本所在目录
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 16:43:19