如何使一个bash子shell退出主调用shell脚本?
具有以下bash脚本:如何使一个bash子shell退出主调用shell脚本?,bash,exit,exit-code,subshell,Bash,Exit,Exit Code,Subshell,具有以下bash脚本: #!/bin/bash set -e function foo() { # commands that might fails and I want to exit my script ... echo "result I need as output" } my_var=$(foo) echo "I don't want this if there is an error inside foo" 使用set-e(在bash4.4.19中)似乎不适用
#!/bin/bash
set -e
function foo() {
# commands that might fails and I want to exit my script
...
echo "result I need as output"
}
my_var=$(foo)
echo "I don't want this if there is an error inside foo"
使用set-e
(在bash4.4.19
中)似乎不适用于子shell,即最后一个echo
命令仍在执行中)。如果foo
中的任何命令以非零退出代码终止,如何编写代码使脚本退出
我正在使用bashGNU bash,版本4.4.19(1)-发行版(x86_64-apple-darwin16.7.0)
,调用我的脚本的结果是(其中点被替换为无效的命令头-此
:
$ ./my_script
head: illegal option -- t
usage: head [-n lines | -c bytes] [file ...]
I don't want this if there is an error inside foo
从评论中更改
管道命令的退出状态是最后一个命令的退出状态,可以使用set-o pipefail
更改此状态,以便管道退出状态将为0
如果任何命令退出状态为0
第一个答案
使用-e
选项时,函数返回非0
退出代码就足够了,例如返回1
在更一般的情况下(没有set-e
),最好使用显式退出
my_var=$(foo) || exit 1
这就足够了,因为子shell可以在标准错误(继承)上写入错误
否则,仔细阅读手册可以解释为什么它不能像您预期的那样工作
设置
-e
如果[…]返回非零状态,则立即退出。如果失败的命令是紧跟在while或until关键字之后的命令列表的一部分、if语句中的测试的一部分、在&&或| |列表中执行的任何命令的一部分(最终&&或| |,[…]之后的命令除外),则shell不会退出
此选项分别应用于shell环境和每个子shell环境(请参见命令执行环境),并可能导致子shell在执行子shell中的所有命令之前退出
[……]
从命令执行环境
生成用于执行命令替换的子shell从父shell继承-e选项的值。当不处于POSIX模式时,Bash将清除此类子shell中的-e选项
因为您没有检查
head
;或者head.| |退出1
,或者在subshell中启用-e
选项my_var=$(set-e;foo)
,第一个更好,因为它是显式的,其他人更容易理解。如果head
实际上是grep…| head…| awk…| xargs…
命令,您如何重写这些管道?使用(grep…|出口1)|(head…|出口1)|…
?对于管道命令,默认情况下,退出状态是管道最后一个命令的退出状态,但也可以通过set-o pipefail
进行更改,请注意,pipefail
在子shell中未清除谢谢!如果您将此选项添加到带有相应注释的答案中,我认为它也会很有用这就是我真正需要的。