我试图同时将输出回显到stderr并将stderr重定向到文件,我注意到重定向的顺序很重要,但是我不明白为什么必须采用这种方式。
使用以下任一命令,文件asap
为空:
echo "Fatal error." >&2 2>asap
echo >&2 "Fatal error." 2>asap
但这可行,将“严重错误”记录到文件asap
中。
echo "Fatal error." 2>asap >&2
为什么?
我试图同时将输出回显到stderr并将stderr重定向到文件,我注意到重定向的顺序很重要,但是我不明白为什么必须采用这种方式。
使用以下任一命令,文件asap
为空:
echo "Fatal error." >&2 2>asap
echo >&2 "Fatal error." 2>asap
但这可行,将“严重错误”记录到文件asap
中。
echo "Fatal error." 2>asap >&2
为什么?
有关大多数必需信息,请参见How to pipe stderr and not stdout。请特别注意'au contraire'注释。请记住,所有重定向都在执行命令之前完成,并且重定向是从左到右处理的。 (管道稍微使故事复杂化。大多数时候,标准输出的管道重定向在进行任何其他重定向之前就完成了。例外是Bash特定的语法|&
。请阅读Bash manual详细信息-然后不要使用|&
。)
请注意,相对于命令名称和参数,重定向可以位于命令行的任何位置。那就是:
<html> xml some -command
与
相同some -command <html >xml
,依此类推。因此,问题中的前两个命令没有区别。 (而且我认为您是自己发现的。)
问题中的第一个命令:
echo "Fatal error." >&2 2>asap
首先将标准输出重定向到当前的标准错误,然后将标准错误重定向到文件(使标准输出指向原始标准错误),然后执行echo
命令。该消息转到原始标准错误(您的终端),而不是文件,因为echo
不会写入标准错误。
最后一条命令:
echo "Fatal error." 2>asap >&2
首先将标准错误发送到文件,然后将标准输出发送到标准错误将要到达的位置(文件),然后执行echo
命令。由于标准输出将发送到文件,因此终端上看不到任何内容。
重定向从左到右发生,因此它们的位置可能有所不同。
例如,两个命令:
runme >somefile 2>&1
runme 2>&1 >somefile
由于顺序,具有不同效果。
首先将标准输出指向文件somefile
,然后将然后标准错误指向该新标准输出(文件)。
第二点将标准错误指向当前标准输出(终端,很可能是)然后将标准输出指向文件。