为啥在 ERR 陷阱中退出 0 时 bash 会抑制标准输出?
Posted
技术标签:
【中文标题】为啥在 ERR 陷阱中退出 0 时 bash 会抑制标准输出?【英文标题】:Why does bash suppress stdout when exit 0 in ERR trap?为什么在 ERR 陷阱中退出 0 时 bash 会抑制标准输出? 【发布时间】:2019-10-07 21:15:10 【问题描述】:我正在尝试在 bash 中设置 ERR 陷阱,并注意到一些奇怪的行为。如果退出代码为0
,则当我运行此脚本时,Bash 似乎不会将我的echo
命令输出到控制台,但是,如果退出代码为非零,则输出文本。这是bash中的错误吗?或者对此有什么解释?
./testing.sh:
#!/bin/bash
set -eE
handleerror()
echo "TEST"
exit 0
trap "handleerror" ERR
OUTPUT=$(mkdir test/test 2>&1)
如果我运行上面的脚本,它什么也不输出。如果我将exit 0
行更改为exit 1
,我会看到以下内容:
> ./testing.sh
TEST
供参考:
> bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)
Copyright (C) 2007 Free Software Foundation, Inc.
【问题讨论】:
【参考方案1】:简答:输出没有被抑制;它由命令替换捕获。更改handleerror
的退出状态会更改它被调用的次数:一次在命令替换内部,一次在在外部。运行bash -x testing.sh
看看有什么不同。
您必须考虑何时实际调用 handlerror
。 mkdir
的失败会触发调用,并且由于在命令替换中调用了handleerror
,因此它的输出被捕获并分配给OUTPUT
。如果你在脚本末尾添加echo "$OUTPUT"
,你会看到
mkdir: test: No such file or directory
TEST
作为脚本的输出。执行此行是因为 handleerror
的 0 退出状态阻止 set -e
提前退出脚本。
现在,将 exit 0
更改为 exit 1
。序列开始相同:mkdir
失败,handleerror
被调用,其输出被命令替换捕获。但是,现在handleerror
本身的退出状态为1,这使得命令替换的退出状态以及赋值语句也为1。这做了两件事:它导致set -e
在echo "$OUTPUT"
运行之前中止脚本,它导致handleerror
运行秒 时间。现在,当您运行脚本时,您看到的只是
TEST
第二次调用handleerror
。
【讨论】:
感谢您的洞察力。我认为我的心智模型与这里实际发生的情况不符。是时候阅读命令替换了。以上是关于为啥在 ERR 陷阱中退出 0 时 bash 会抑制标准输出?的主要内容,如果未能解决你的问题,请参考以下文章