即使使用“set -e”

时间:2017-05-17 03:08:26

标签: bash

考虑以下简单的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并以代码= 0退出。

如果我将gen修改为失败,请改为调用seqqq命令(不存在):

$ ./script.sh; echo $?
./script.sh: line 6: seqqq: command not found
finish
0

它打印来自子shell的错误消息,它不会立即失败并立即退出(使用非零代码)set -e应该这样做;它继续执行并以代码= 0退出。

这背后的解释是什么?注意,如果我只是用我的for循环替换它,它会按预期失败:

#!/bin/bash
set -eou pipefail
IFS=$'\n\t'

gen() {
  seqqq 0 3
}

gen # <-- fails and exits here with code=127

echo "finish"

1 个答案:

答案 0 :(得分:4)

set -e似乎在命令替换的上下文中无效,如:

for c in $(gen); do
  echo c
done

但是,set -e在直接函数调用的上下文中起作用,如:

gen

使用set -e编写可靠的shell脚本很难或几乎不可能。请改用显式错误处理。您可以在此处详细了解:BashFAQ/105