python子进程不捕获pv命令的stderr

Posted

技术标签:

【中文标题】python子进程不捕获pv命令的stderr【英文标题】:python subprocess does not capture stderr of a pv command 【发布时间】:2022-01-18 13:14:03 【问题描述】:

我需要用 python 运行一些 bash 脚本并显示输出。其中一些脚本包含一些pv 命令,但我无法从subprocess 获得pv 输出。

import subprocess as sp

p = sp.Popen(["./script.sh"], shell=False, bufsize=1, stdout=sp.PIPE, stderr=sp.STDOUT, universal_newlines=True)

p.wait()

print(p.returncode)
print(p.stdout.read())
#!/bin/bash

set -e

echo "aaa"
echo "bbb" >&2

pv -L 1000 -F "%t %b %r %e" /path/to/some/file | cat > /tmp/foo

运行这个 python 脚本我只是得到echo的输出:

$ python script.py 
0
aaa
bbb

【问题讨论】:

【参考方案1】:

pv 对是否在终端中运行很敏感。如果您想捕获它的输出,请使用pv -f 选项强制它显示进度指示器,即使它没有连接到终端。

对于更复杂的场景,您可能必须使用pty 之类的东西来模拟在终端下运行。

(当然,最好使用原生 Python 进度条,例如 tqdm。)

【讨论】:

谢谢,使用pty 我可以让它工作,但我的用例非常复杂(并行运行多个脚本)并且使用pty 变得很困难。无论如何,我发现pv 有一个-f 标志:“强制输出。通常,如果标准错误不是终端,则 pv 不会输出任何视觉显示。此选项强制它这样做。”,这解决了我的问题 哦,很好,我会将其添加到答案中。我本想检查一下,但分心了。

以上是关于python子进程不捕获pv命令的stderr的主要内容,如果未能解决你的问题,请参考以下文章

杀死父进程后将标准输入传递给子进程

Python:用 glib 监控子进程输出?

python:运行一个超时的进程并捕获stdout、stderr和退出状态[重复]

合并Python脚本的子进程'stdout和stderr,同时保持它们可区分

Python监控子进程的stderr和stdout

Python子进程 - stderr在读取后擦除