我尝试在 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.
最佳答案
简短回答:输出没有被抑制;它被命令替换捕获。更改 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
产生。
关于bash - 为什么 bash 在 ERR 陷阱中退出 0 时抑制标准输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56238922/