我想在发生任何故障(包括管道内部故障)时终止脚本。在 bash 中可以set -eo pipefail
,但这在 ksh 中不起作用。
例子:
# x
set -eo pipefail
false | true
echo "done: $?" # reached in ksh, unexpected
false
echo "done2" # not reached in either shell, as expected
bash x # prints nothing, as expected
ksh x # done: 1
ksh --version # ... 93u+ 2012-08-01
为什么 ksh 在这种情况下不会退出?
编辑:添加另一个测试
我将其与其他 shell 进行了比较,得到了不同的结果:
-bash-5.0$ zsh -c 'set -eo pipefail; false | true; exit 2' ; echo $?
1
-bash-5.0$ ksh -c 'set -eo pipefail; false | true; exit 2'; echo $?
2
-bash-5.0$ bash -c 'set -eo pipefail; false | true; exit 2' ; echo $?
1
除了 ksh 中的错误之外,我不明白是什么导致了这种行为。根据 man ksh 的说法:
-e Unless contained in a ⎪⎪ or && command, or the command
following an if while or until command or in the
pipeline following !, if a command has a non-zero exit # Pipeline does not follow !
status, execute the ERR trap, if set, and exit. This # Pipeline has a non-zero exit status
mode is disabled while reading profiles.
pipefail
A pipeline will not complete until all
components of the pipeline have completed, and
the return value will be the value of the last
non-zero command to fail or zero if no command
has failed.
答案1
它看起来像是 ksh93u+ 引入的回归。 ksh93u 在这方面按预期工作(以及 zsh、bash、mksh、yash 和 busybox sh)。
我刚刚提出了这个问题https://github.com/ksh93/ksh/issues/121
现在固定在https://github.com/ksh93/ksh/commit/c049eec854d506ad6110eb50c769b10224c60075,自 v1.0.0-beta.1 起包含