如何处理未绑定的变量而不重复?

如何处理未绑定的变量而不重复?

请考虑以下常见模式来处理命令退出状态:

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'

不过,如果您需要检查是否存在非空值,则需要单独执行此操作。

相关内容