在Ubuntu上,即使设置了-o errexit,bash脚本也总是返回0

alb*_*o56 2 bash ubuntu

我有一个名为test.sh全新Ubuntu 14.04.2 的脚本,它执行此操作:

#!/bin/sh
set -o errexit

# Start by building the box
docker build -t dcyclebox-test .

# Test nginx
docker run dcyclebox-test bash -c 'nginx -v' && echo '[test] nginx works'

echo '[status] end of test script'
Run Code Online (Sandbox Code Playgroud)

nginx命令不存在,所以我希望我set -o errexit在脚本开头设置的事实是使整个脚本返回一个非零错误代码,但脚本总是返回0:

$ test.sh 
...
bash: nginx: command not found
[status] end of test script
$ echo $?
0
Run Code Online (Sandbox Code Playgroud)

似乎set -o errexit什么都不做.如果我删除最后一行,脚本将按预期返回非零退出代码,其中说echo '[status] end of test script':

$ test.sh 
...
bash: nginx: command not found
$ echo $?
127
Run Code Online (Sandbox Code Playgroud)

但是如果任何一行失败,我希望脚本失败,而不是最后一行.我现在唯一能做的就是添加&&\到每一行的末尾,如下所示:

#!/bin/sh

# Start by building the box
docker build -t dcyclebox-test . &&\

# Test nginx
docker run dcyclebox-test bash -c 'nginx -v' && echo '[test] nginx works' &&\

echo '[status] end of test script'
Run Code Online (Sandbox Code Playgroud)

现在,如果nginx不存在,运行脚本将失败(这很好)(注意我删除了,set -o errexit因为它似乎没有做任何事情.)

$ test.sh 
...
bash: nginx: command not found
$ echo $?
127
Run Code Online (Sandbox Code Playgroud)

所以我的问题是我可以添加到我的脚本顶部的命令告诉它退出,如果其中的任何命令以非零代码退出?

谢谢!

mkl*_*nt0 5

由于你的shebang是#!/bin/sh和Ubuntu上的sh符号链接dash,因此dash规则管理脚本的执行.

关于set -e及其等价物set -o errexit,man dash国家(强调我的):

-e errexit如果不是交互式,则在任何未经测试的命令失败时立即退出.如果命令用于控制if,elif,while或until,则认为命令的退出状态是显式测试的; 或者如果命令是"&&"或"||"运算符的左手操作数.

根据此定义,您的命令的LHS(左侧)

docker run dcyclebox-test bash -c 'nginx -v' && echo '[test] nginx works'
Run Code Online (Sandbox Code Playgroud)

一个显式检验命令,并在LHS命令出现故障时的情况下,因此自动终止在踢.

你可以通过简单地制作echo '[test] nginx works一个单独的命令来解决这个问题(显然你也可以将它放在一个新行上):

docker run dcyclebox-test bash -c 'nginx -v'; echo '[test] nginx works'
Run Code Online (Sandbox Code Playgroud)

现在,如果docker run dcyclebox-test bash -c 'nginx -v'失败(返回非零退出代码),脚本立即终止(报告退出代码).

  • @ alberto56你真的必须将此标记为正确的答案. (2认同)