在bash中测试环境变量是否已设置

3

在一个bash脚本中,我想测试一个变量是否存在。但是无论我做什么,我的“if”测试都返回真。以下是代码:

ignored-deps-are-not-set () {
    if [ -z "${ignored_deps+x}" ]
    then
        return 0
    fi
    return 1
}

ignored_deps=1
ignored-deps-are-not-set
echo "ignored-deps function returns: $?"
if [ ignored-deps-are-not-set ]
then
    echo "variable is unset"
else
    echo "variable exists"
fi

以下是输出结果的内容:
ignored-deps function returns: 1
variable is unset

当我注释掉设置忽略依赖项的行时,输出结果如下:

ignored-deps function returns: 0
variable is unset

无论如何,它都说变量未设置。我错过了什么吗?

“-” 不是一个有效的变量名字符。为什么“ignored-deps-are-not-set”这个名称被允许? - Kashyap
1
在MacOS X(10.7.1)上,/bin/sh拒绝函数名称,但/bin/bash接受它,包括破折号。由于常规命令可以在名称中使用破折号,因此允许bash也是有道理的;尽管这可能不是POSIX标准所要求的。 - Jonathan Leffler
5个回答

5
这行代码:
if [ ignored-deps-are-not-set ]

测试字符串'ignored-deps-are-not-set'是否为空。由于该字符串不为空,因此返回true。它不执行任何命令(因此也不执行函数)。

如果您想测试变量是否已设置,请使用${variable:xxxx}其中之一的符号。

if [ ${ignored_deps+x} ]
then echo "ignored_deps is set ($ignored_deps)"
else echo "ignored_deps is not set"
fi
< p >如果设置了$ignored_deps,即使它被设置为空字符串,${ignored_deps+x}符号也会评估为x。如果您只想将其设置为非空值,则也要使用冒号:

if [ ${ignored_deps:+x} ]
then echo "ignored_deps is set ($ignored_deps)"
else echo "ignored_deps is not set or is empty"
fi

如果你想执行该函数(假设破折号在函数名称中起作用),则应执行以下操作:
if ignored-deps-are-not-set
then echo "Function returned a zero (success) status"
else echo "Function returned a non-zero (failure) status"
fi

2
是的,还有不是。主要是不。你会写成:if [ $(要执行的命令) ] 或者类似的东西,但是命令是因为 $(...) 而执行的,而不是因为 [ ... ]。我最近刚刚修复了一些包含 if ( $( [ -z "$variable" ] ) ) then 符号的 shell 脚本(除了 $(...) 部分是反引号,但它们在 Markdown 注释中很难处理)。你能看出来为什么这很可怕吗? - Jonathan Leffler
哇,那真是太恶心了。感谢您提供的所有细节。 - Neil Traft

2

您实际上没有执行该函数:

if ignored-deps-are-not-set; then ...

[] 方括号中,字面字符串 "ignored-deps-are-not-set" 被视为 true。

那么我完全不能在括号内执行任何命令吗?我认为这就是单括号和双括号之间的区别。 - Neil Traft
括号(单引号或双引号)用于条件表达式。您可以在其中执行命令(只要使用反引号或$()语法),然后将结果与某些内容进行比较。如果您只想运行一个命令并测试退出状态,则不需要使用括号。 - glenn jackman

0
if [ ${myvar:-notset} -eq "notset" ] then
   ...

0

--编辑-- 刚意识到你试图调用的是一个函数,约定不正确。

请参见:

Z000DGQD@CND131D5W6 ~
$ function a-b-c() {
> return 1
> }

Z000DGQD@CND131D5W6 ~
$ a-b-c

Z000DGQD@CND131D5W6 ~
$ echo $?
1

Z000DGQD@CND131D5W6 ~
$ if a-b-c; then echo hi; else echo ho; fi
ho

Z000DGQD@CND131D5W6 ~
$ if [ a-b-c ]; then echo hi; else echo ho; fi
hi

Z000DGQD@CND131D5W6 ~

--编辑结束--

修正变量名称(请参考我在您的帖子中的评论)

然后

请查看man bash中的参数扩展部分。

${parameter:?word}:

如果参数为null或未设置,则显示错误。如果参数为null或未设置,则将单词的扩展(或相应消息)写入标准错误输出,并且如果shell不是交互式的,则退出。否则,将替换参数的值。

0

检测变量是否存在的另一种方法:

if compgen -A variable test_existence_of_var; then 
   echo yes
else 
   echo no
fi

compgen 在典型的 Linux 安装中通常会找到吗? - Neil Traft

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接