我是Bash的新手,我很难弄清楚为什么当我使用set -o errexit并且命令失败时,脚本没有退出。
似乎是因为我宣布了一个局部变量!
请告诉我如何同时使用局部变量和设置-o errexit。
示例:
#!/bin/bash
set -o errexit
set -o nounset
set -o pipefail
function test {
local output=$(ls --badoption)
echo "error code is $?"
echo "output=$output"
}
test
结果:
./test.sh
ls: illegal option -- -
usage: ls [-ABCFGHLOPRSTUWabcdefghiklmnopqrstuwx1] [file ...]
error code is 0
output=
可是:
#!/bin/bash
set -o errexit
set -o nounset
set -o pipefail
function test {
output=$(ls --badoption)
echo "error code is $?"
echo "output=$output"
}
test
结果:
ls: illegal option -- -
usage: ls [-ABCFGHLOPRSTUWabcdefghiklmnopqrstuwx1] [file ...]
答案 0 :(得分:4)
这是因为set -o errexit
(或使用-e
运行bash)仅影响简单命令(如bash手册页中所定义)。 cmd
中的local output=$(cmd)
不被视为简单命令,因此-e
没有任何影响($?
与cmd
没有任何关系退出)。一个简单的解决方法是通过替换:
local output=$(ls --badoption)
使用:
local output
output=$(ls --badoption)
在我的测试中执行您想要的所有内容,它会立即退出,如果您将ls --badoption
替换为ls
,则可以正常工作,并在调用{{1}之前设置output
然后在显示test
之后回显它output
确实是test
的本地。
答案 1 :(得分:2)
local
的文档说:
返回状态为零,除非在函数外部使用local,提供了无效的名称,或者name是只读变量。
因此local
命令的返回状态不受命令替换中执行的命令是否成功的影响。
正如他的回答中指出的那样,你可以通过分离声明和局部变量的赋值来获得你想要的效果。使用命令替换的普通赋值的返回状态是执行命令的子shell的返回状态。