首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >子流程stderr与sys.stderr的比较

子流程stderr与sys.stderr的比较
EN

Stack Overflow用户
提问于 2018-10-12 13:19:34
回答 1查看 395关注 0票数 3

我不确定这个问题是Python问题还是shell问题。

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

代码语言:javascript
复制
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")

当我运行这段代码时,控制台上的ouptut (来自stderr)如下:

--你好 ls:无法访问‘*..foobar’:没有这样的文件或目录 命令失败 -再见

如果我将stderr重定向到一个文件(例如使用python myscript.py 2>日志),则该文件包含以下内容:

ls:无法访问‘*..foobar’:没有这样的文件或目录 --你好 命令失败 -再见

是否有一种方法来保持文件中消息的顺序(除了在子进程调用中对文件使用stderr的显式重定向)?

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-12 13:24:56

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

代码语言:javascript
复制
sys.stderr.write("--Hello\n")
sys.stderr.flush()

stdio在连接到终端时是行缓冲的,连接到管道时使用固定的缓冲区。您正在编写一个\n换行符,该字符在连接到终端时触发刷新,但如果没有按行刷新,则无法在stderr退出时在最后一次刷新之前触发缓冲区刷新。

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

代码语言:javascript
复制
print("--Hello", file=sys.stderr, flush=True)

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

代码语言:javascript
复制
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属性。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52780404

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档