bash -e 用法简述

可以看到很多 shell脚本在开头第一行都写着 #!/bin/sh -e,那么这里的 '-e'是什么意思呢?简单来说,使用 '-e'后,shell脚本在执行过程中,若遇到某条命令返回非零状态,则会立即退出,并且上述用法等同于 set -e语句,在 GNU Bash 的官方文档中对 '-e'有一个明确的解释:

-e
Exit immediately if a pipeline (see Pipelines), which may consist of a single simple command (see Simple Commands), a list (see Lists of Commands), or a compound command (see Compound Commands) returns a non-zero status. The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test in an if statement, part of any command executed in a && or || list except the command following the final && or ||, any command in a pipeline but the last, or if the command’s return status is being inverted with !. If a compound command other than a subshell returns a non-zero status because a command failed while -e was being ignored, the shell does not exit. A trap on ERR, if set, is executed before the shell exits.
This option applies to the shell environment and each subshell environment separately (see Command Execution Environment), and may cause subshells to exit before executing all the commands in the subshell.
If a compound command or shell function executes in a context where -e is being ignored, none of the commands executed within the compound command or function body will be affected by the -e setting, even if -e is set and a command returns a failure status. If a compound command or shell function sets -e while executing in a context where -e is ignored, that setting will not have any effect until the compound command or the command containing the function call completes.

上述内容所讲的使用规则及场景比较复杂,在实际使用时,若不确定某种用法是否符合预期,则应提前测试。下面展示几种常规用法:
1、函数调用返回非零状态
test.sh代码:

#!/bin/sh -e

foo() {
	echo "foo()"
	return 1
}

foo
echo "test.sh done!"

test.sh运行结果:

$ ./test.sh 
foo()

2、子 shell以非零状态退出
sub.sh代码:

#!/bin/sh

echo "sub.sh done"
exit 1

test.sh代码:

#!/bin/sh -e

./sub.sh
echo "test.sh done"

test.sh运行结果:

$ ./test.sh 
sub.sh done

3、子 shell中的函数调用返回非零状态
sub.sh代码:

#!/bin/sh

foo_in_sub() {
	echo "foo_in_sub()"
	return 1
}

foo_in_sub
echo "sub.sh done"

test.sh代码:

#!/bin/sh -e

./sub.sh
echo "test.sh done"

test.sh运行结果:

$ ./test.sh 
foo_in_sub()
sub.sh done
test.sh done

可以看到,当子 shell中的函数调用返回非零状态时,子 shell并不会立即退出,父 shell也不会立即退出。但如果是通过 source ./sub.sh的方式在父 shell中直接调用子 shell里面的函数,那么当出现函数返回非零状态时父 shell会立即退出(在更复杂的使用场景下,可能不是这样,需要大家确认)。

4、使能 '-e'后,如何进行错误处理?
有时候虽然我们使能了 '-e',但还是希望能够感知错误的发生,以及对错误进行处理,而不是直接退出。此时我们可以使用 "||"表达式来进行错误处理,如下所示:
sub.sh代码:

#!/bin/sh

echo "sub.sh done"
exit 1

test.sh代码:

#!/bin/sh -e

failed=false
./sub.sh || failed=true

if $failed ; then
	echo "sub.sh exec failed"
fi
echo "test.sh done"

test.sh运行结果:

$ ./test.sh 
sub.sh done
sub.sh exec failed
test.sh done

5、与 set -e相反,使用 set +e可以关掉上述功能,示例略。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值