Answers:
一旦输出已经打印,就无法判断。在这种情况下,两个stdout
和stderr
都连接到终端,因此,当文本出现在终端上时,有关写入哪个流的信息已经丢失。程序将它们合并到终端之前。
在上述情况下,您可以做的是与命令一起运行stdout
并stderr
重定向到其他地方,然后看看会发生什么。或运行两次,一次stdout
重定向到/dev/null
,一次stderr
重定向到/dev/null
,然后查看哪种情况会导致文本显示。
您可以通过在命令行末尾添加大写字母来重定向stdout
到,也可以通过添加来重定向到。/dev/null
>/dev/null
stderr
/dev/null
2>/dev/null
您可以使用重定向标准输出> file
,并使用重定向标准错误2> file
。许多现代的Shell支持重定向到命令,因此您可以sed
用来突出显示哪个输出来自哪个流:
$ ls 2> >(sed 's/^/2: /') > >(sed 's/^/1: /')
1: unity_support_test.0
1: vmwareDnD
$ ls foo 2> >(sed 's/^/2: /') > >(sed 's/^/1: /')
2: ls: cannot access foo: No such file or directory
(echo "this is stdout"; echo "this is stderr" >&2) > >(sed 's/.*/\x1b[32m&\x1b[0m/') 2> >(sed 's/.*/\x1b[31m&\x1b[0m/')
在annotate-output
从Debian的脚本,devscripts
让你做这个选择:
$ annotate-output ls -ld /test
14:54:22 -: Started ls -ld /test
14:54:22 E: ls: cannot access /test: No such file or directory
14:54:22 -: Finished with exitcode 2
第二列分别用O
和指示stdout和stderr E
。
有一些注意事项,主要的问题在其他答案中也有提及:事后您不能这样做。尽管外壳程序负责最初设置它们,但是外壳程序和终端都不知道任意程序如何使用其文件描述符。
此方法使用fifo,写入fifo的行为可能不同于写入tty,并且写入两个不同的fifo肯定不同(潜在的时序/交织问题)。而且,它不适合交互式使用,例如,annotate-output bash
这不是一个很好的计划,但对于许多其他目的也很有用。在回答有关stdin / stdout / stderr着色的相关问题时,有许多脚本和shell函数示例,最可靠的是stderrd,它使用(大多数)程序的运行时修改来修改写入stderr的数据。
Anko链接到的这个问题在相关主题上有很好的答案:为stdout / stderr输出着色: 我可以配置我的shell来以不同颜色打印STDERR和STDOUT吗?
bash
使用while read
循环并date
为stdout或stderr的每一行运行一个命令的脚本,因此它的效率要比cmd > >(ts '%T O:') 2> >(ts '%T E:')
同等效率低得多。
除了其他答案,指向/proc/$PID/fd
(尽管它没有回答问题)很有趣:
$ cat > /dev/null 2> /tmp/blablah &
[1] 3073
[1]+ Stopped cat > /dev/null 2> /tmp/blablah
$ ls -l /proc/3073/fd
total 0
lrwx------ 1 kampde kampde 64 Feb 24 11:43 0 -> /dev/pts/33
l-wx------ 1 kampde kampde 64 Feb 24 11:43 1 -> /dev/null
l-wx------ 1 kampde kampde 64 Feb 24 11:43 2 -> /tmp/blablah
如您所见,在这里您可以看到为进程打开的文件描述符。0
是STDIN
,1
是STDOUT
和2
是STDERR
。如果您没有重定向STDOUT或STDERR,则会看到/dev/pts/33
(至少在此示例中),因为它们将指向终端。
注意:/proc/$PID
仅适用于正在运行的进程。在这种情况下,我使用了cat
没有参数,因此直到我关闭STDIN
。时它才结束。我也已在后台执行了该命令,因此,出于本示例的考虑,我将立即获得PID。
不清楚您要问什么,但这可能会有所帮助
ls -ld /
echo $? # Exit status 0 returned because command executed successfully.
ls -ld /test
echo $? # Non-zero exit status returned -- command failed to execute
如果退出代码为0,则仅表示命令已正确执行(stdout),如果退出代码不同于0(stderr),则可以在此处找到含义。
stdout
和非零暗示stderr
吗?
stderr
并返回正确的错误代码,或者写入stdout
并返回错误的错误代码。实际上,尝试find /root
-假设您不是以root身份运行,则应该打印2行-将“ / root”打印到stdout
,并将“ find:/ root:权限被拒绝”打印到stderr
。并且find返回错误的返回码。