我如何知道是否在Bash中设置了变量?

例如,如何检查用户是否向函数提供了第一个参数?

function a {
    # if $1 is set ?
}

当前回答

如果您希望测试变量是否绑定或未绑定,即使在启用了nounset选项后,这也能很好地工作:

set -o noun set

if printenv variableName >/dev/null; then
    # variable is bound to a value
else
    # variable is unbound
fi

其他回答

if [ "$1" != "" ]; then
  echo \$1 is set
else
  echo \$1 is not set
fi

尽管对于参数,通常最好测试$#,我认为这是参数的数量。

if [ $# -gt 0 ]; then
  echo \$1 is set
else
  echo \$1 is not set
fi

要测试是否设置了变量var:[${var+x}]。

若要测试变量是否按名称设置:[${!name+x}]。

要测试是否设置了位置参数:[${N+x}],其中N实际上是一个整数。

这个答案与莱昂内尔的答案几乎相似,但通过省略-z来探索一种更为简约的方法。

要测试是否设置了命名变量,请执行以下操作:

function is_set {
    local v=$1
    echo -n "${v}"
    if [ ${!v+x} ]; then
        echo " = '${!v}'"
    else
        echo " is unset"
    fi
}

要测试是否设置了位置参数:

function a {
    if [ ${1+x} ]; then
        local arg=$1
        echo "a '${arg}'"
    else
        echo "a: arg is unset"
    fi
}

测试表明,不需要特别注意空格和有效的测试表达式。

set -eu

V1=a
V2=
V4=-gt
V5="1 -gt 2"
V6="! -z 1"
V7='$(exit 1)'

is_set V1
is_set V2
is_set V3
is_set V4
is_set V5
is_set V6
is_set V7

a 1
a
a "1 -gt 2"
a 1 -gt 2
$ ./test.sh

V1 = 'a'
V2 = ''
V3 is unset
V4 = '-gt'
V5 = '1 -gt 2'
V6 = '! -z 1'
V7 = '$(exit 1)'
a '1'
a: arg is unset
a '1 -gt 2'
a '1'

最后,请注意set-eu,它保护我们避免常见错误,例如变量名中的拼写错误。我建议使用它,但这意味着未设置的变量和带有空字符串的变量集之间的区别得到了正确处理。

要检查变量是否设置为非空值,请使用[-n“$x”],正如其他人已经指出的那样。

大多数情况下,最好将具有空值的变量与未设置的变量以相同的方式处理。但如果需要,您可以区分这两个:[-n“${x+set}”](如果设置了x,则“${x+set}”扩展为set,如果未设置x,则扩展为空字符串)。

要检查是否传递了参数,请测试$#,这是传递给函数(或不在函数中时传递给脚本)的参数数(请参见Paul的答案)。

如果你想检查$@中的任何内容,我找到了一个更好的代码。

if [[ $1 = "" ]]
then
  echo '$1 is blank'
else
  echo '$1 is filled up'
fi

为什么会这样?$@中的所有内容都存在于Bash中,但默认情况下为空,因此test-z和test-n无法帮助您。

更新:您还可以计算参数中的字符数。

if [ ${#1} = 0 ]
then
  echo '$1 is blank'
else
  echo '$1 is filled up'
fi

如果未设置,则要退出

这对我很有用。如果没有设置参数,我希望脚本退出并显示错误消息。

#!/usr/bin/env bash

set -o errexit

# Get the value and empty validation check all in one
VER="${1:?You must pass a version of the format 0.0.0 as the only argument}"

运行时返回错误

peek@peek:~$ ./setver.sh
./setver.sh: line 13: 1: You must pass a version of the format 0.0.0 as the only argument

仅检查,不退出-空和未设置无效

如果您只想检查值set=VALID或unset/empty=INVALID,请尝试此选项。

TSET="good val"
TEMPTY=""
unset TUNSET

if [ "${TSET:-}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TEMPTY:-}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID
if [ "${TUNSET:-}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID

或者,即使是短期测试;-)

[ "${TSET:-}"   ] && echo "VALID" || echo "INVALID"
[ "${TEMPTY:-}" ] && echo "VALID" || echo "INVALID"
[ "${TUNSET:-}" ] && echo "VALID" || echo "INVALID"

仅检查,不退出-仅空为无效

这就是问题的答案。如果您只想检查值set/empty=VALID或unset=INVALID,请使用此选项。

注意,“..-1}”中的“1”无关紧要,它可以是任何东西(比如x)

TSET="good val"
TEMPTY=""
unset TUNSET

if [ "${TSET+1}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TEMPTY+1}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TUNSET+1}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID

短期测试

[ "${TSET+1}"   ] && echo "VALID" || echo "INVALID"
[ "${TEMPTY+1}" ] && echo "VALID" || echo "INVALID"
[ "${TUNSET+1}" ] && echo "VALID" || echo "INVALID"

我把这个答案献给了@mklement0(comments),他要求我准确回答这个问题。

参考:2.6.2参数扩展