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

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

function a {
    # if $1 is set ?
}

当前回答

为了明确回答OP关于如何确定变量是否已设置的问题,Lionel的回答是正确的:

if test "${name+x}"; then
    echo 'name is set'
else
    echo 'name is not set'
fi

这个问题已经有很多答案,但没有一个提供真正的布尔表达式来明确区分变量值。

以下是我得出的一些明确表达:

+-----------------------+-------------+---------+------------+
| Expression in script  | name='fish' | name='' | unset name |
+-----------------------+-------------+---------+------------+
| test "$name"          | TRUE        | f       | f          |
| test -n "$name"       | TRUE        | f       | f          |
| test ! -z "$name"     | TRUE        | f       | f          |
| test ! "${name-x}"    | f           | TRUE    | f          |
| test ! "${name+x}"    | f           | f       | TRUE       |
+-----------------------+-------------+---------+------------+

顺便说一下,这些表达式是等价的:测试<表达式><=>〔<表达式>〕

其他需谨慎使用的歧义表达:

+----------------------+-------------+---------+------------+
| Expression in script | name='fish' | name='' | unset name |
+----------------------+-------------+---------+------------+
| test "${name+x}"     | TRUE        | TRUE    | f          |
| test "${name-x}"     | TRUE        | f       | TRUE       |
| test -z "$name"      | f           | TRUE    | TRUE       |
| test ! "$name"       | f           | TRUE    | TRUE       |
| test ! -n "$name"    | f           | TRUE    | TRUE       |
| test "$name" = ''    | f           | TRUE    | TRUE       |
+----------------------+-------------+---------+------------+

其他回答

虽然这里所述的大多数技术都是正确的,但Bash 4.2支持对变量的存在进行实际测试(man-Bash),而不是测试变量的值。

[[ -v foo ]]; echo $?
# 1

foo=bar
[[ -v foo ]]; echo $?
# 0

foo=""
[[ -v foo ]]; echo $?
# 0

值得注意的是,与许多其他方法(如使用[-z)不同,这种方法在set-u/set-o nounset模式下用于检查未设置的变量时不会导致错误。

在Bash中,可以在[[]]内置函数中使用-v:

#! /bin/bash -u

if [[ ! -v SOMEVAR ]]; then
    SOMEVAR='hello'
fi

echo $SOMEVAR

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

set -o noun set

if printenv variableName >/dev/null; then
    # variable is bound to a value
else
    # variable is unbound
fi
case "$1" in
 "") echo "blank";;
 *) echo "set"
esac

这是我每天使用的:

#
# Check if a variable is set
#   param1  name of the variable
#
function is_set() { [[ $(eval echo "\${${1}+x}") ]]; }

这在Linux和Solaris以及Bash 3.0下运行良好。

$ myvar="TEST"
$ is_set myvar ; echo $?
0

$ myvar=
$ is_set myvar ; echo $?
0

$ unset myvar
$ is_set myvar ; echo $?
1