在 Linux
下,把命令的输出重定向到文件是一个很常见的操作,但如何正确区分
stdout
和 stderr
可不是一件容易的事。初学者如果不仔细理解概念,直接按照直观来理解的话,对于这个问题是非常容易混淆的,我们来看这样一个小例子:
提问:这两条命令有什么区别?
很多对 Bash
不熟悉的同学看到了以后立刻说:“我知道我知道!第一条命令是把
stderr
重定向到 stdout
,然后把
stdout
重定向到
command.log
,因此命令执行完之后所有输出的内容都在
command.log
里面。第二条命令是把
stdout
重定向到 command.log
里,然后把 stderr
重定向到 stdout
里,因此命令执行完后 command.log
里只有
stdout
的输出,stderr
的输出还在屏幕上。”
这个答案正确么?很遗憾,每个句子里面“因此”前面的部分是完全正确的,但“因此”后面的部分完全错误,根本原因还是因为,大家把“重定向”的意思理解错了。为了正确理解这个问题,我们还是来仔细解释一下概念吧。
先看第一个命令,我们先做 2>&1
,原先 2
指向的是屏幕,1
指向的是屏幕,因此做完这个重定向以后,2
里的所有内容被重定向到 1,也就是 stderr
被重定向到屏幕上。
然后,我们做 > command.log
,原先 1
指向的是屏幕,重定向之后,1
指向的变成了文件,因此做完这个重定向以后,1
里的所有内容被重定向到文件,也就是 stdout
被重定向到文件里。
总之,命令一重定向的结果是,stderr
被重定向到屏幕上,stdout
被重定向到文件里,命令执行完后,文件里仅仅有
stdout
的输出。
理解了第一个命令之后,再看第二个命令也就很好理解了。我们先做
> command.log
,原先 1
指向的是屏幕,做完这个重定向以后,1
里的所有内容被重定向到 command.log
,也就是
stdout
被重定向到文件里。
然后,我们做 2>&1
,原先 2
指向的是屏幕,1 指向的是文件
command.log
,注意,1
已经被重定向到文件里了,因此,重定向之后,2
指向的也变成了文件,也就是 stderr
也被重定向到文件里。
总之,命令二重定向的结果是,stdout
和
stderr
都被重定向到文件里,命令执行完后,文件里有
stdout
和 stderr
的全部输出。
看明白了么?重定向的过程其实很简单,但由于和直观感受不一致,往往导致初学者在这里犯很多错误。希望这篇文章能解决初学者在输出重定向方面的疑惑。