bash中stdout和stderr的顺序

时间:2017-07-26 02:14:41

标签: bash redirect

ls test.mp4  test.sh 1>/tmp/text  2>&1
cat   /tmp/text
ls: cannot access test.sh: No such file or directory
test.mp4

为什么结果不是以下顺序?

test.mp4
ls: cannot access test.sh: No such file or directory

首先执行1>/tmp/text,test.mp4在test.sh之前找到 哪个效果如何呢?

2 个答案:

答案 0 :(得分:4)

这与bash无关。它只是反映了C标准库I / O函数缓冲输出的方式。

这里是man setvbuf在Linux系统上的有用摘录(解释主要来自C和Posix标准,但我认为在此摘录中很容易找到并理解) 。第二段是对你所看到的行为的解释。

  

可用的三种缓冲类型是无缓冲,块缓冲和行缓冲。当输出流未缓冲时,一旦写入,信息就会出现在目标文件或终端上;当它被块缓冲时,许多字符被保存起来并写成块;当它是行缓冲时,字符被保存,直到输出换行符或从连接到终端设备的任何流中读取输入(通常是stdin)。函数fflush(3)可用于提前阻止块。 (见fclose(3)。)

     

通常所有文件都是块缓冲的。如果流引用终端(正如stdout通常那样),则它是行缓冲的。默认情况下,标准错误流stderr始终是无缓冲的。

所以,回顾一下。 stdout通常是指终端,因此是行缓冲的,但您已将其重定向到文件,因此它是块缓冲的。但是,stderr始终是无缓冲的,无论它是否已被重定向。

因此,打印到stderr的任何内容都会立即显示,而打印到stdout的任何内容都将被保留,直到缓冲区填满(在Linux上,通常为8kb)。

请注意,当ls检测到stdout不是终端时,它会默认设置-1标记(每行一个文件名)。否则,它将默认设置-x标志(与一行中适合的文件名一样多)。这意味着您将在终端上看到相同的反转而没有任何重定向:

$ ls good bad
ls: cannot access bad: No such file or directory
good

答案 1 :(得分:2)

stdout似乎在_exit上进行了缓冲和刷新。 另一方面,斯特德尔则更为紧迫。我不认为bash会等到_exit才能刷新它。如果它被缓冲了。