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

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

function a {
    # if $1 is set ?
}

当前回答

[[ $foo ]]

Or

(( ${#foo} ))

Or

let ${#foo}

Or

declare -p foo

其他回答

我总是使用这个,因为任何第一次看到代码的人都很容易理解:

if [ "$variable" = "" ]
    then
    echo "Variable X is empty"
fi

如果要检查是否为空;

if [ ! "$variable" = "" ]
    then
    echo "Variable X is not empty"
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

要测试是否设置了变量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 [[ -z $SOME_VAR ]]; then read -p "Enter a value for SOME_VAR: " SOME_VAR; fi
echo "SOME_VAR=$SOME_VAR"

如果您不使用SOME_VAR代替我的$SOME_VVAR,它会将其设置为空值;$这是工作所必需的。

如果未设置,则要退出

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

#!/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参数扩展