假设有这么一段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默认带有换行符。