假设有这么一段python3程序:

import sys
print ("123")
sys.stderr.write("stderr1 ")

现在想要把程序的输出以及错误信息都存在文件中。

一开始是这么做的:

python ./test.py 2>&1 > t1

结果终端依然输出了信息

stderr1

而文件t1里面的内容是

[ss@localhost test]$ cat t1
123

搜索之后发现,shell解析重定向是从左往右按顺序解析。也就是先解析2>&1把stderr重定向到stdout也就是输出到终端,接着解析>t1把stdout重定向到t1文件。

所以为了达成目标,需要改成

python ./test.py > t1 2>&1 

这样就会先把stdout重定向,再重定向stderr,都输出到t1文件。

转载介绍:

文件描述符(file descriptor)
名称                类型           文件描述符    操作
标准输入       standard input           0    <,<<
标准输出       standard output          1    >,>>
标准错误输出    standard error output    2    2>,2>>
文件描述符的存储位置位于 /proc/self/fd ,文件描述符是通过一系列软链接指向的默认输出设备,这里我们的默认设备就是模拟终端

https://www.cnblogs.com/divent/p/5773861.html

----------------

 

python ./test.py 2>&1 | cat >t1

 似乎pipe只会接收stdout的输入,参考解释:

Note that the sequence of I/O redirections is interpreted left-to-right, but pipes are set up before the I/O redirections are interpreted. 
File descriptors such as 1 and 2 are references to open file descriptions. The operation 2>&1 makes file descriptor 2 aka stderr refer to the same open
file description as file descriptor 1 aka stdout is currently referring to (see dup2() and open()).
The operation >/dev/null then changes file descriptor 1 so that it refers to an open file description for /dev/null,
but that doesn't change the fact that file descriptor 2 refers to the open file description which file descriptor 1 was originally pointing to — namely, the pipe.

如果是:

python ./test.py | cat >t1

那么t1中只会有stdout的输出。也可以尝试:

python ./test.py 2>&1 >/dev/null | cat >t1

只接收stderr输出。

 

import sys
print ("123")
sys.stdout.flush()
sys.stderr.write("stderr1 ")
print ("23")
sys.stdout.flush()

测试stderr是否有缓冲,结果显示似乎也是有缓冲的(行缓冲)。

python3中stderr重定向到文件时,似乎是全缓冲的

"python3": sys.stderr is line buffered at both the TextIOWrapper layer and may be fully buffered at the binary BufferedWriter layer if the output is redirected to a file

https://bugs.python.org/issue13601

 

#!/usr/bin/python
import sys
print("stdout1",end='')
sys.stderr.write("stderr1 ")
print("stdout2 ",end='')
sys.stderr.write("stderr2 ")
sys.stderr.flush()
print ("123")
#sys.stdout.flush()
sys.stderr.write("error\n")

终端直接运行输出:

stderr1 stderr2 stdout1 stdout2 123
error

缓存模式和https://www.cnblogs.com/starRebel/p/8359455.html相似,需要注意的是python中的print默认带有换行符。

 

posted on 2018-07-20 16:39  SimbaStar  阅读(169)  评论(0编辑  收藏  举报