请考虑以下常见模式来处理命令退出状态:
if COMMAND; then
echo success
else
echo failure
fi
使用相同的变量赋值(给定set -o nounset
)不起作用:
$ if foo="$no_such_variable"; then echo success; else echo failure; fi
bash: no_such_variable: unbound variable
A变量替换检查也不起作用:
$ if foo="${no_such_variable:?}"; then echo success; else echo failure; fi
bash: no_such_variable: parameter null or not set
有没有办法捕获语句中赋值的返回码if
?我试图避免使用标准if [[ $# -eq N ]]
解决方法,因为它将该语句与脚本其余部分中的每个参数分配相结合,而不是在每个分配本身捕获任何问题。
这与 Python 模式类似if (foo := bar()):
。
答案1
您可能会尝试围绕未设置变量的内置测试构建一些内容:test -v no_such_variable
。例如,一个函数setvar
可以执行此测试,并且仅在正常时才进行分配:
set -o nounset
setvar(){
declare -n var=$1 # -n is like ${!var} but for lvalue too
declare value=$2
[ -v ${value} ] && var="${!value}"
}
if setvar foo no_such_variable
then echo success
else echo failure
fi
答案2
有没有办法捕获 if 语句中赋值的返回码?
我不确定您可以在此处查看有用的退出状态。
set -u
/下的变量扩展的nounset
作用${var?message}
是退出外壳如果变量未设置。此后您无法查看脚本中的任何退出值,因为脚本不再运行。
如果您的作业包含命令替换,则退出状态将来自那里。否则,分配就会成功。
如果要检查变量是否未设置,则需要使用备用值扩展 ,${var+string}
如果设置了变量(不使用其值),则该值扩展为给定字符串,如果未设置,则不扩展任何内容。
所以
if [ "${var+set}" ]; then
foo="$var"
echo '$var copied to $foo'
else
echo '$var is unset'
fi
或者,您知道,只需禁用它,nounset
这样复制就不会失败:
set +u
foo="$var"
echo '$var copied to $foo'
不过,如果您需要检查是否存在非空值,则需要单独执行此操作。