Posix shell:区分空变量和不存在变量

时间:2016-02-26 13:07:12

标签: variables posix sh

在纯/bin/sh中,我如何区分空变量,未设置变量和不存在(未定义)变量。

以下是这种情况:

# Case 1: not existing
echo "${foo}"

# Case 2: unset
foo=
echo "${foo}"

# Case 3: Empty
foo=""
echo "${foo}"

现在我想检查这三个案例中的每一个。 如果案例2和案例3实际上是相同的,那么我必须至少能够区分它们和案例1.

有什么想法吗?

更新 解决了Matteo

以下是代码的外观:

#foo  <-- not defined
bar1=
bar2=""
bar3="a"

if ! set | grep '^foo=' >/dev/null 2>&1; then
    echo "foo does not exist"
elif [ -z "${foo}" ]; then
    echo "foo is empty"
else
    echo "foo has a value"
fi

if ! set | grep '^bar1=' >/dev/null 2>&1; then
    echo "bar1 does not exist"
elif [ -z "${bar1}" ]; then
    echo "bar1 is empty"
else
    echo "bar1 has a value"
fi

if ! set | grep '^bar2=' >/dev/null 2>&1; then
    echo "bar2 does not exist"
elif [ -z "${bar2}" ]; then
    echo "bar2 is empty"
else
    echo "bar2 has a value"
fi


if ! set | grep '^bar3=' >/dev/null 2>&1; then
    echo "bar3 does not exist"
elif [ -z "${bar3}" ]; then
    echo "bar3 is empty"
else
    echo "bar3 has a value"
fi

结果:

foo does not exist
bar1 is empty
bar2 is empty
bar3 has a value

3 个答案:

答案 0 :(得分:1)

我不了解sh,但在bashdash中,您可以针对案例1与案例2/3进行echo ${TEST:?Error}。从快速浏览wikibooks开始,它似乎也适用于bourne shell。

你可以在bash和dash中使用它(使用$?来获取错误代码)

echo ${TEST:?"Error"}
bash: TEST: Error
[lf@dell:~/tmp/soTest] echo $?
1
[lf@dell:~/tmp/soTest] TEST2="ok"
[lf@dell:~/tmp/soTest] echo ${TEST2:?"Error"}
ok
[lf@dell:~/tmp/soTest] echo $?
0
[lf@dell:~/tmp/soTest] dash
$ echo ${TEST3:?"Error"}       
dash: 1: TEST3: Error
$ TEST3=ok
$ echo ${TEST3:?"Error"}
ok

答案 1 :(得分:1)

如果var未设置,则可以使用$ {var?}语法抛出错误;如果未设置var或为空,则可以使用$ {var:?}抛出错误。举个具体的例子:

$ unset foo
$ test -z "${foo?unset}" && echo foo is empty || echo foo is set to $foo
-bash: foo: unset
$ foo=
$ test -z "${foo?unset}" && echo foo is empty || echo foo is set to $foo
foo is empty
$ foo=bar
$ test -z "${foo?unset}" && echo foo is empty || echo foo is set to $foo
foo is set to bar

答案 2 :(得分:0)

您可以使用set

  

如果未指定选项或参数,则set应在当前语言环境的归类序列中写入所有shell变量的名称和值。每个名称应以单独的一行开头,格式为:

您可以列出要检查的变量名称的所有变量(set)和grep

set | grep '^foo='