bash中stderr重定向的意外行为

时间:2017-06-07 20:01:57

标签: bash shell sh

我对stdout / stderr的理解是脚本可以登录到stderr,并在stdout中生成'有用的'输出,如果需要,它将由调用进程管道或捕获。

在实践中,这并不像我想象的那样有效。

➜ cat test.sh 
echo diagnostic blah blah 1>&2
echo result

我的理解是,如果我做echo $(./test.sh),我应该得到'结果',因为'诊断blah blah'被发送到stderr。但是,我得到了:

➜ echo $(./test.sh)            
diagnostic blah blah
result

这可以正常工作,这表明重定向到stderr实际上正在工作:

➜ echo $(./test.sh 2>/dev/null) 
result

所以我想我对如何在shell脚本中处理输出的理解是错误的。我错过了什么?

作为另一个例子,我不希望这起作用:

➜ ./test.sh | grep diagnostic
diagnostic blah blah

2 个答案:

答案 0 :(得分:1)

您的测试过程没有提供任何区分stdout和stderr的方法。请考虑一下:

echo "stderr only here:"
result=$(./test.sh)      ## stderr goes straight to TTY, stdout gets captured
echo
echo "writing the previously-captured stdout:"
printf '%s\n' "$result"  ## printf is better-defined than echo

答案 1 :(得分:0)

Charles Duffy是对的 - test.sh脚本按预期工作。

我正在调查的初始问题的根本原因更简单 - 我将所有日志输出从我的脚本重定向到stderr,但我没有重定向脚本中的其他命令的输出(在我的情况下{{ 1}})