bash中stdout和stderr的顺序

2023-11-29

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

Maybe 1>/tmp/text首先执行,test.mp4位于test.sh之前。
造成什么效果呢?


这与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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

bash中stdout和stderr的顺序 的相关文章

随机推荐