1> file.log 2>& 1和1> file.log 2> file.log

时间:2014-08-02 17:54:32

标签: bash

这两个bash命令之间有区别吗?

$ some_command 1>file.log 2>&1

$ some_command 1>file.log 2>file.log 

2 个答案:

答案 0 :(得分:4)

此命令:

some_command 1>file.log 2>file.log 

重定向stdout和stderr的方法不正确。

如果您使用noclobber设置set -o noclobber选项,则实际上会导致此错误:

-bash: file.log : cannot overwrite existing file

但是,如果您使用noclobber然后

关闭set +C选项
some_command 1>file.log 2>file.log 

虽然使用

更好,但不会产生上述错误
some_command 1>file.log 2>&1

答案 1 :(得分:1)

的区别。

bash$ (echo foo; echo bar 1>&2) 1>test.out 2>&1
bash$ cat test.out
foo
bar
bash$ (echo foo; echo bar 1>&2) 1>test.out 2>test.out
bash$ cat test.out
bar
bash$ 

作为anubhava notes,如果设置了noclobber,则第二个变体甚至根本不运行(即使您先删除test.out文件)。但是如果没有设置这个选项,就像我在这里的例子那样,bash在这里做的是打开文件两次,而不是打开它一次然后使用dup系统调用。

在这种情况下,关键区别在于dup - ed文件描述符与其原始文件共享其搜索偏移量,而单独的open则没有。因此:

  • 在上面的第一个test.out示例中,stdout(描述符1)和stderr(描述符2)共享搜索偏移量,该偏移量最初为零。 echo foo命令运行,将其输出发送到其stdout,该stdout将转到偏移量为0的文件,并写入包括换行符在内的四个字节。这会使偏移量最多变为4. echo bar命令然后运行,将其输出发送到stderr, 1 ,它将转移到偏移量为4的文件,记住偏移量为共享 - 并将bar和换行符写入文件。 (然后将偏移量提升到8,但没有其他任何东西使用该文件,因此它将被关闭并且丢弃偏移量。)

  • 然而,在第二个test.out示例中,stdout和stderr具有单独的搜索偏移量。两者都在偏移0处向test.out打开。echo foo命令运行,将foo和换行符写入stdout并将偏移量更新为4.然后运行echo bar命令,将bar和换行符写入stderr,但再次返回0 ,覆盖前一个字符串。 (和以前一样,偏移量突然增加到4次,但一切都完成了,两个描述符关闭,丢弃了偏移量。)

这就是为什么第一次测试在文件中以两行结束,但第二次测试只有一行。


1 从技术上讲,echo bar也写入了它的stdout,但我们使用1>&2将stderr(描述符2)dup转到stdout(描述符1)。和以前一样,这个dup会导致偏移量被共享。请注意,dup重定向仅在echo bar命令的持续时间内继续,之后所有内容都将恢复。这种回归是我们必须在测试本身中对两个echo命令加以括号的原因,以便test.out的外部重定向在两个 echo调用中持续存在。 (从技术上讲,我们重定向运行两个fork命令的echo - ed子shell的描述符。)