考虑以下简单的 bash 脚本:
#!/bin/bash
set -eou pipefail
IFS=$'\n\t'
gen() {
seq 0 3
}
for c in $(gen); do
echo c
done
echo "finish"
它设置了 set -e
,所以当出现故障时,它应该以非零退出代码退出。
它将调用 gen
函数并打印 seq 0 3
的输出,将打印 finish
并以 code=0 退出。
如果我将 gen
修改为失败,例如,通过调用 seqqq
命令(它不存在)来代替:
$ ./script.sh; echo $?
./script.sh: line 6: seqqq: command not found
finish
0
它打印来自子 shell 的错误消息,它不会像 set -e
应该做的那样立即失败并立即退出(使用非零代码);它继续执行并以 code=0 退出。
这背后的解释是什么?请注意,如果我只是像这样用我的 for 循环替换,它会按预期失败:
#!/bin/bash
set -eou pipefail
IFS=$'\n\t'
gen() {
seqqq 0 3
}
gen # <-- fails and exits here with code=127
echo "finish"
最佳答案
似乎 set -e
在命令替换的上下文中无效,如:
for c in $(gen); do
echo c
done
但是,set -e
确实在直接函数调用的上下文中起作用,如:
gen
用 set -e
编写可靠的 shell 脚本很难或几乎不可能。请改用显式错误处理。您可以在这里阅读更多相关信息:BashFAQ/105
关于bash - 即使使用 "set -e",for 循环中的函数调用也不会失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44014857/