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

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

function a {
    # if $1 is set ?
}

当前回答

阅读bash手册页的“参数扩展”部分。参数扩展并不能为正在设置的变量提供常规测试,但如果未设置参数,可以对其执行一些操作。

例如:

function a {
    first_arg=${1-foo}
    # rest of the function
}

如果分配了firstarg,则将其设置为等于$1,否则将使用值“foo”。如果绝对必须采用单个参数,并且不存在良好的默认值,则可以在未给定参数时退出并显示错误消息:

function a {
    : ${1?a must take a single argument}
    # rest of the function
}

(注意:作为null命令的用法,它只是扩展其参数的值。在本例中,我们不想对$1做任何操作,如果未设置,只需退出)

其他回答

如果你和我一样,你所寻找的其实是

“如果设置了变量,bash仅运行命令”

你希望这是一行,所以下面这行是你想要的

仅适用于Bash 4.2或更高版本

仅在设置时运行

if [[ -v mytest ]]; then echo "this runs only if variable is set"; fi

仅在未设置时运行

if [[ ! -v mytest2 ]]; then echo "this runs only if variable 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,它保护我们避免常见错误,例如变量名中的拼写错误。我建议使用它,但这意味着未设置的变量和带有空字符串的变量集之间的区别得到了正确处理。

要检查非空/非零字符串变量,即如果已设置,请使用

if [ -n "$1" ]

它与-z相反。我发现自己使用-n多于-z。

您可以像这样使用它:

if [ -n "$1" ]; then
  echo "You supplied the first parameter!"
else
  echo "First parameter not supplied."
fi

声明一个简单函数is_set,它使用Declare-p直接测试变量是否存在。

$ is_set() {
    declare -p $1 >/dev/null 2>&1
}

$ is_set foo; echo $?
0

$ declare foo

$ is_set foo; echo $?
1

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

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

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