在Bash中,如何测试变量是否以"-u"模式定义

Ram*_*mon 51 bash

我刚刚set -u在bash中发现它帮助我找到了几个以前看不见的bug.但我还有一个场景,我需要在计算某个默认值之前测试是否定义了变量.我想出的最好的是:

if [ "${variable-undefined}" == undefined ]; then
    variable="$(...)"
fi
Run Code Online (Sandbox Code Playgroud)

哪个有效(只要变量没有字符串值undefined).我想知道是否有更好的方法?

Ram*_*mon 53

这是我发现最适合我的,从其他答案中获取灵感:

if [ -z "${varname-}" ]; then
  ...
  varname=$(...)
fi
Run Code Online (Sandbox Code Playgroud)

  • 在描述各种运算符之前,在手册页中的快速语句中描述了无冒号的版本.这很容易错过.如果`varname`未设置*或*设置为空字符串,`$ {varname:-foo}`扩展为`foo`; 如果未设置`varname`,`$ {varname-foo}`只会扩展为`foo`. (9认同)
  • 有人可以解释为什么`"$ {varname - }"`**和**`"$ {varname: - }"`有效吗?我对第一部作品感到惊讶. (4认同)
  • http://www.tldp.org/LDP/abs/html/parameter-substitution.html $ {varname-}是$ {varname-default}的一种形式.如果未设置varname,则返回默认值,在本例中为空字符串. (3认同)
  • 恕我直言的问题的最佳答案. (2认同)

Tod*_*obs 30

什么是行不通的:测试零长度字符串

您可以通过几种方式测试未定义的字符串.使用标准测试条件如下所示:

# Test for zero-length string.
[ -z "$variable" ] || variable='foo'
Run Code Online (Sandbox Code Playgroud)

但是,这不适用set -u.

什么有效:有条件的分配

或者,您可以使用条件赋值,这是一种类似Bash的方法.例如:

# Assign value if variable is unset or null.
: "${variable:=foo}"
Run Code Online (Sandbox Code Playgroud)

由于Bash处理此表达式扩展的方式,您可以安全地使用它set -u而不会出现"bash:variable:unbound variable"错误.

  • 什么是领导`:`做什么? (4认同)
  • @AndrewFerrier这个问题具体是指如果未设置变量则指定默认值; 虽然有一些有效的用例用于测试是否设置了变量而没有随后设置它,但这个问题并不需要它. (3认同)
  • 这并不能完全回答这个问题,因为它没有提供一种测试未定义变量的方法,只是一种设置它的方法。如果需要其他逻辑,这将无济于事。 (2认同)

Fel*_*old 7

在bash 4.2和更新版本中,有一种明确的方法来检查变量是否设置,即使用-v.然后可以像这样实现问题中的示例:

if [[ ! -v variable ]]; then
   variable="$(...)"
fi
Run Code Online (Sandbox Code Playgroud)

请参阅http://www.gnu.org/software/bash/manual/bashref.html#Bash-Conditional-Expressions

如果你只想设置变量,如果它还没有设置,你可能更喜欢沿着这些方面做一些事情:

variable="${variable-$(...)}"

请注意,这不会处理已定义但空的变量.


kev*_*rpe 5

上面的答案不是动态的,例如,如何测试定义了名称为“ dummy”的变量?尝试这个:

is_var_defined()
{
    if [ $# -ne 1 ]
    then
        echo "Expected exactly one argument: variable name as string, e.g., 'my_var'"
        exit 1
    fi
    # Tricky.  Since Bash option 'set -u' may be enabled, we cannot directly test if a variable
    # is defined with this construct: [ ! -z "$var" ].  Instead, we must use default value
    # substitution with this construct: [ ! -z "${var:-}" ].  Normally, a default value follows the
    # operator ':-', but here we leave it blank for empty (null) string.  Finally, we need to
    # substitute the text from $1 as 'var'.  This is not allowed directly in Bash with this
    # construct: [ ! -z "${$1:-}" ].  We need to use indirection with eval operator.
    # Example: $1="var"
    # Expansion for eval operator: "[ ! -z \${$1:-} ]" -> "[ ! -z \${var:-} ]"
    # Code  execute: [ ! -z ${var:-} ]
    eval "[ ! -z \${$1:-} ]"
    return $?  # Pedantic.
}
Run Code Online (Sandbox Code Playgroud)

相关:如何检查Bash中是否设置了变量?