【问题标题】:Unexpected behavior for stderr redirection in bashbash 中 stderr 重定向的意外行为
【发布时间】:2017-06-08 04:18:28
【问题描述】:

我对 stdout/stderr 的理解是,脚本可以登录到 stderr,并在 stdout 中产生“有用”的输出,如果需要,调用进程将通过管道传输或捕获这些输出。

实际上,这并不像我想象的那样工作。

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

我的理解是,如果我这样做echo $(./test.sh),我应该只得到“结果”,因为“诊断等等”已发送到标准错误。但是,我得到:

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

这可以正常工作,这表明重定向到 stderr 确实有效:

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

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

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

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

【问题讨论】:

  • 您希望如何知道哪些内容被进程替换捕获并随后由echo 发出,哪些内容通过stderr 直接发送到您的TTY?毕竟,最终目的地是双向的 TTY。
  • 好点 - 将编辑演示。
  • 管道到 grep 只是巧合,你可以管道到任何东西,它会显示 diagnostic blah blah,因为 stderr 被发送到 TTY 而不是通过管道。
  • ^ 是的 ➜ ./test.sh | grep anything-at-all diagnostic blah blah

标签: bash shell sh


【解决方案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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2017-11-30
      • 2011-02-05
      • 1970-01-01
      • 2010-09-07
      • 2010-10-01
      • 2018-06-21
      • 1970-01-01
      • 2010-09-30
      • 2012-03-09
      相关资源
      最近更新 更多