子流程标准系统标准

2024-03-28 13:11:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我不确定这个问题是Python问题还是shell问题。你知道吗

我有一个Python程序,它对一个命令使用子进程调用,这个命令可以在stderr上发出错误消息。我自己的程序也使用系统标准记录错误。下面是一个简单的示例,其中一个命令(ls*.foobar)失败:

import sys,subprocess

sys.stderr.write("--Hello\n")
try:
    subprocess.check_call("ls *.foobar",shell=True)
except subprocess.CalledProcessError as e:
    sys.stderr.write("Command failed\n")
sys.stderr.write("--Bye\n")

运行此代码时,控制台上的输出(来自stderr)如下所示:

--Hello
ls: cannot access '*.foobar': No such file or directory
Command failed
--Bye

如果我将stderr重定向到一个文件(例如,使用pythonmyscript.py文件以下文件包含>;日志:

^{2}$

有没有办法保持文件中消息的顺序(除了在子进程调用中对文件使用stderr的显式重定向之外)?你知道吗

这个问题类似于一些标准的stdout/stderr问题,但是在这里,一切都应该在stderr上。你知道吗


Tags: 文件命令程序消息hello标准进程错误
1条回答
网友
1楼 · 发布于 2024-03-28 13:11:34

您需要将数据写入器刷新到stderr描述符:

sys.stderr.write(" Hello\n")
sys.stderr.flush()

当连接到终端时,stdio是线缓冲的,当连接到管道时,使用固定缓冲。您正在编写一个\n换行符,它在连接到终端时触发一个刷新,但是如果没有每行刷新,您就不能在Python退出时,在最后一次刷新之前编写足够的stderr来触发缓冲区刷新。你知道吗

如果使用print(..., file=sys.stderr),可以通过添加flush=True来告诉print()发出flush()调用:

print(" Hello", file=sys.stderr, flush=True)

处理此问题的另一种方法是“捕获并释放”子进程的stderr输出:

sys.stderr.write(" Hello\n")
try:
    subprocess.check_call("ls *.foobar", shell=True, stderr=subprocess.PIPE)
except subprocess.CalledProcessError as e:
    sys.stderr.write(e.stderr)
    sys.stderr.write("Command failed\n")
sys.stderr.write(" Bye\n")

stderr=subprocess.PIPE加法告诉subprocess捕获命令的stderr输出,您可以将该输出作为CalledProcessError异常的e.stderr属性找到。你知道吗

相关问题 更多 >