【问题标题】:How can I pipe stderr and still test if the command failed?如果命令失败,我如何管道 stderr 并仍然测试?
【发布时间】:2019-10-10 01:46:02
【问题描述】:

我想为 cron 编写一个单行代码:

  1. 将 STDOUT 和 STDERR 重定向到记录器
  2. 测试命令是否失败
  3. 如果发生这种情况,请执行操作

我有一个脚本,它会打印一些东西然后严重退出。

script.sh:

SCRIPT=`basename "$0"`
echo $SCRIPT is running...
\>&2 echo $SCRIPT has failed!
exit 1

当我在没有管道到记录器的情况下运行脚本时,一切都很好。当我将所有内容通过管道传输到记录器以供日后查看时,错误检查失败。有没有办法让管道和错误检查同时工作?

\>script.sh
script.sh is running...
script.sh failed!

\>script.sh || echo foo
script.sh is running...
script.sh failed!
foo

\>script.sh 2>&1 | logger || echo foo
\>

【问题讨论】:

  • 检查logger 是否在cron 的PATH 上,或使用其完整路径。
  • 记录器的管道工作正常。问题是,一旦我通过管道传输到记录器,错误条件不再触发命令的后半部分(echo foo)。

标签: bash pipe stderr error-checking


【解决方案1】:

一种方式:

set -o pipefail
script.sh |& logger || echo foo

另一种方式:

(script.sh |& logger; exit ${PIPESTATUS[0]}) || echo foo

man bash:

PIPESTATUS 一个数组变量,包含最近执行的进程的退出状态值列表 前台管道(可能只包含一个命令)。

【讨论】:

  • >>(script.sh |& logger; 退出 ${PIPESTATUS[0]}) || echo foo 就像一个魅力。这是什么法宝?你能向我解释一下为什么会这样吗?
  • @coldspringhead 为您添加了 PIPESTATUS 注释。 |&stdoutstderr 都重定向到管道中。 () 启动一个子shell。
猜你喜欢
  • 2019-03-18
  • 1970-01-01
  • 2012-03-19
  • 1970-01-01
  • 2013-09-13
  • 2020-02-29
  • 2015-03-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多