使用"set -o nounset"测试是否在bash中设置变量

vin*_*one 87 unix bash shell

以下代码以未绑定的变量错误退出.如何解决这个问题,同时仍然使用set -onounset选项?

#!/bin/bash

set -o nounset

if [ ! -z ${WHATEVER} ];
 then echo "yo"
fi

echo "whatever"
Run Code Online (Sandbox Code Playgroud)

Ang*_*lom 83

#!/bin/bash

set -o nounset


VALUE=${WHATEVER:-}

if [ ! -z ${VALUE} ];
 then echo "yo"
fi

echo "whatever"
Run Code Online (Sandbox Code Playgroud)

在这种情况下,VALUE如果WHATEVER未设置,则最终为空字符串.我们正在使用{parameter:-word}扩展,您可以man bash在"参数扩展"下查找.

  • `:-`检查变量是否未设置*或*为空.如果你想检查*是否*是否未设置,请使用`-`:`VALUE = $ {WHATEVER-}`.另外,一种更易读的方法来检查变量是否为空:`if ["$ {WHATEVER + defined}"= defined]; 然后回声定义; 否则回声未定义; fi` (15认同)
  • 如果[!-z $ {VALUE}]; 如果[!-z $ {WHATEVER: - }]; (8认同)
  • 是否有理由使用“`!-z`”而不是“`-n`”? (3认同)

l0b*_*0b0 28

如果要获得预期的结果,则需要引用变量:

check() {
    if [ -n "${WHATEVER-}" ]
    then
        echo 'not empty'
    elif [ "${WHATEVER+defined}" = defined ]
    then
        echo 'empty but defined'
    else
        echo 'unset'
    fi
}
Run Code Online (Sandbox Code Playgroud)

测试:

$ unset WHATEVER
$ check
unset
$ WHATEVER=
$ check
empty but defined
$ WHATEVER='   '
$ check
not empty
Run Code Online (Sandbox Code Playgroud)

  • 不,支持`-`,`+`,`:+`和`:-`.前者检测变量是否为*set*,后者检测它是*set**还是**empty*.来自`man bash`:"省略冒号导致仅对未设置的参数进行测试." (8认同)
  • 没关系=)。你是对的。我不知道我是怎么错过的。 (2认同)

小智 8

那一个班轮怎么样?

[ -z "${VAR:-}" ] && echo "VAR is not set or is empty" || echo "VAR is set to $VAR"
Run Code Online (Sandbox Code Playgroud)

-z 检查是否为空或未设置变量

  • 不,`-z` 只检查下一个参数是否为空。`-z` 只是 `[` 命令的一个参数。变量扩展发生在 `[ -z` 可以做任何事情之前。 (2认同)

小智 7

您可以使用

if [[ ${WHATEVER:+$WHATEVER} ]]; then
Run Code Online (Sandbox Code Playgroud)

if [[ "${WHATEVER:+isset}" == "isset" ]]; then
Run Code Online (Sandbox Code Playgroud)

可能更具可读性。

  • @Jens 这个问题是特定于 bash 的,包括特定于 bash 的 `set -o nounset` 。如果您将“#!/bin/bash”放在脚本顶部,实际上最好使用 bash 的增强功能。 (3认同)

Acu*_*nus 7

假设:

$ echo $SHELL
/bin/bash
$ /bin/bash --version | head -1
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
$ set -o nounset
Run Code Online (Sandbox Code Playgroud)

如果您希望非交互式脚本打印错误,并在变量为null或未设置时退出:

$ [[ "${HOME:?}" ]]

$ [[ "${IAMUNBOUND:?}" ]]
bash: IAMUNBOUND: parameter null or not set

$ IAMNULL=""
$ [[ "${IAMNULL:?}" ]]
bash: IAMNULL: parameter null or not set
Run Code Online (Sandbox Code Playgroud)

如果您不希望脚本退出:

$ [[ "${HOME:-}" ]] || echo "Parameter null or not set."

$ [[ "${IAMUNBOUND:-}" ]] || echo "Parameter null or not set."
Parameter null or not set.

$ IAMNULL=""
$ [[ "${IAMUNNULL:-}" ]] || echo "Parameter null or not set."
Parameter null or not set.
Run Code Online (Sandbox Code Playgroud)

你甚至可以使用[],而不是[[]]以上,但后者是优选的猛砸.

注意上面冒号的作用.来自文档:

换句话说,如果包含冒号,运算符将测试参数的存在性及其值不为空; 如果省略冒号,则运算符仅测试是否存在.

显然没有必要-n-z.

总之,我通常可以使用[[ "${VAR:?}" ]].根据这些示例,如果变量为null或未设置,则会输出错误并退出.