请不仅查看已接受的答案,还请查看其他答案。
为什么将 STDOUT 和 STDERR 重定向到同一个文件不起作用,尽管它看起来与 1>[FILENAME] 2>&1 相同?
下面是一个例子:
perl -e 'print "1\n" ; warn "2\n";' 1>a.txt 2>a.txt
cat a.txt
# outputs '1' only.
Run Code Online (Sandbox Code Playgroud)
嗯,为什么?我认为这是有效的,因为...... STDOUT 被重定向到 a.txt,STDERR 也是如此。STDERR 怎么了?
use*_*686 62
使用1>a.txt 2>&1,文件描述符#1 被复制到#2。它们都引用相同的“打开文件”,并且共享当前位置和 r/w 模式。(实际上使用 2>&1 和 2<&1 之间根本没有区别。)
使用1>a.txt 2>a.txt,两个文件描述符都是独立打开的,并且具有单独的光标位置。(文件也被截断了两次。)如果你向 fd #1 写入“Hello”,它的位置会前进到字节 5,但 fd #2 保持在字节 0。打印到 fd #2 只会覆盖从 0 开始的数据.
这很容易看出第二次写入是否较短:
$ perl -e 'STDOUT->print("abcdefg\n"); STDOUT->flush; STDERR->print("123");' >a.txt 2>a.txt
$ cat a.txt
123defg
Run Code Online (Sandbox Code Playgroud)
请注意,Perl 具有内部缓冲,因此在此示例中,需要显式 flush() 以确保在 fd #2 数据之前写入 fd #1 数据。否则,流将在退出时以不可预测的顺序刷新。
为了比较,如果文件描述符是共享的,则写入只是相互跟随:
$ perl -e 'STDOUT->print("abcdefg\n"); STDOUT->flush; STDERR->print("123");' >a.txt 2>&1
$ cat a.txt
abcdefg
123
Run Code Online (Sandbox Code Playgroud)
Eug*_*eck -2
您的两个重定向都会截断文件,因此第二个(按执行时间顺序)将覆盖第一个。尝试
rm a.txt ; touch a.txt ; perl -e 'print "1\n" ; warn "2\n";' 1>>a.txt 2>>a.txt
Run Code Online (Sandbox Code Playgroud)
或者只是使用相同的文件描述符
perl -e 'print "1\n" ; warn "2\n";' 1>a.txt 2>&1
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2860 次 |
| 最近记录: |