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

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

function a {
    # if $1 is set ?
}

当前回答

要查看变量是否为非空,我使用

if [[ $var ]]; then ...       # `$var' expands to a nonempty string

如果变量未设置或为空,则相反:

if [[ ! $var ]]; then ...     # `$var' expands to the empty string (set or not)

要查看变量是否已设置(空或非空),我使用

if [[ ${var+x} ]]; then ...   # `var' exists (empty or nonempty)
if [[ ${1+x} ]]; then ...     # Parameter 1 exists (empty or nonempty)

如果变量未设置,则进行相反的测试:

if [[ ! ${var+x} ]]; then ... # `var' is not set at all
if [[ ! ${1+x} ]]; then ...   # We were called with no arguments

其他回答

声明一个简单函数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

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

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

如果要检查是否为空;

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

我很惊讶没有人尝试编写一个shell脚本来以编程方式生成这个臭名昭著的难以摸索的表。既然我们在这里试图学习编码技术,为什么不用代码表达答案?:)这是我的看法(应该在任何POSIX shell中都适用):

H="+-%s-+-%s----+-%s----+-%s--+\n"       # table divider printf format
R="| %-10s | %-10s | %-10s | %-10s |\n"  # table row printf format

S='V'     # S is a variable that is set-and-not-null
N=''      # N is a variable that is set-but-null (empty "")
unset U   # U is a variable that is unset

printf "$H" "----------" "-------" "-------" "---------";
printf "$R" "expression" "FOO='V'" "FOO='' " "unset FOO";
printf "$H" "----------" "-------" "-------" "---------";
printf "$R" "\${FOO:-x}" "${S:-x}" "${N:-x}" "${U:-x}  "; S='V';N='';unset U
printf "$R" "\${FOO-x} " "${S-x} " "${N-x} " "${U-x}   "; S='V';N='';unset U
printf "$R" "\${FOO:=x}" "${S:=x}" "${N:=x}" "${U:=x}  "; S='V';N='';unset U
printf "$R" "\${FOO=x} " "${S=x} " "${N=x} " "${U=x}   "; S='V';N='';unset U
#                                  "${N:?x}" "${U:?x}  "
printf "$R" "\${FOO:?x}" "${S:?x}" "<error>" "<error>  "; S='V';N='';unset U
#                                            "${U?x}   "
printf "$R" "\${FOO?x} " "${S?x} " "${N?x} " "<error>  "; S='V';N='';unset U
printf "$R" "\${FOO:+x}" "${S:+x}" "${N:+x}" "${U:+x}  "; S='V';N='';unset U
printf "$R" "\${FOO+x} " "${S+x} " "${N+x} " "${U+x}   "; S='V';N='';unset U
printf "$H" "----------" "-------" "-------" "---------";

以及运行脚本的输出:

+------------+------------+------------+------------+
| expression | FOO='V'    | FOO=''     | unset FOO  |
+------------+------------+------------+------------+
| ${FOO:-x}  | V          | x          | x          |
| ${FOO-x}   | V          |            | x          |
| ${FOO:=x}  | V          | x          | x          |
| ${FOO=x}   | V          |            | x          |
| ${FOO:?x}  | V          | <error>    | <error>    |
| ${FOO?x}   | V          |            | <error>    |
| ${FOO:+x}  | x          |            |            |
| ${FOO+x}   | x          | x          |            |
+------------+------------+------------+------------+

该脚本缺少了一些功能,比如在发生(或不发生)副作用分配时显示,但也许其他更有野心的人希望以此为出发点,并以此为出发。

用于检查变量是否已声明/未设置的函数

包括空$array=()

以下函数测试给定名称是否作为变量存在

# The first parameter needs to be the name of the variable to be checked.
# (See example below)

var_is_declared() {
    { [[ -n ${!1+anything} ]] || declare -p $1 &>/dev/null;}
}

var_is_unset() {
    { [[ -z ${!1+anything} ]] && ! declare -p $1 &>/dev/null;} 
}

通过首先测试变量是否已(未)设置,可以避免对声明的调用(如果不需要的话)。然而,如果$1包含空$array=()的名称,则调用声明将确保获得正确的结果传递给/dev/null的数据不多,因为只有在变量未设置或为空数组时才会调用declare。

该功能将在以下条件下进行测试:

a、 #未声明a=;#已声明a=“foo”;#已声明a=();#已声明a=(“”);#已声明取消设置a;#未声明a、 #未设置a=;#未设置a=“foo”;#未设置a=();#未设置a=(“”);#未设置取消设置a;#未设置

.

有关详细信息一个测试脚本可以看到我对“如何检查bash中是否存在变量?”问题的回答。备注:declare-p的类似用法,正如Peregring lk的答案所示,确实是巧合。否则我当然会把它归功于你!