如何判断一个字符串是不是在bash shell脚本定义?如何判断一个字符串是不是在bash shel

2019-05-12 17:10发布

如果我要检查空字符串我会做

[ -z $mystr ]

但如果我要检查是否变量都被定义? 或者有没有在bash脚本没有区别?

Answer 1:

我觉得你是以后的答案是隐含的(如果不说)由Vinko的答案 ,虽然它没有说出来简单。 为了区分VAR是否被设置,但空或没有设置,你可以使用:

if [ -z "${VAR+xxx}" ]; then echo VAR is not set at all; fi
if [ -z "$VAR" ] && [ "${VAR+xxx}" = "xxx" ]; then echo VAR is set but empty; fi

你也许可以在第二行的两个测试组合成一个具有:

if [ -z "$VAR" -a "${VAR+xxx}" = "xxx" ]; then echo VAR is set but empty; fi

但是,如果你阅读的Autoconf的文档,你会发现,他们不建议用“相结合方面-a ”,并使用单独的简单测试联合做推荐&& 。 我还没有遇到一个系统,其中有一个问题; 这并不意味着他们没有使用存在(但他们很可能是极为罕见的,这些天,即使他们不是在遥远的过去罕见)。

你可以找到这些细节,以及其他相关的外壳参数扩展 ,在test[命令和条件表达式在Bash的手册。


我最近通过电子邮件询问这个答案的问题:

您可以使用两个测试,我的理解,第二个好,但不是第一个。 更确切地说,我不理解变量扩展的需要

 if [ -z "${VAR+xxx}" ]; then echo VAR is not set at all; fi 

这是不是完成相同的?

 if [ -z "${VAR}" ]; then echo VAR is not set at all; fi 

公平的问题 - 答案是:“不,你更简单的替代不会做同样的事情。”

假设我测试之前写:

VAR=

您的测试会说:“VAR没有设置在所有”,但我会说(通过暗示,因为它呼应什么)“VAR设置,但其价值可能是空的”。 试试这个脚本:

(
unset VAR
if [ -z "${VAR+xxx}" ]; then echo JL:1 VAR is not set at all; fi
if [ -z "${VAR}" ];     then echo MP:1 VAR is not set at all; fi
VAR=
if [ -z "${VAR+xxx}" ]; then echo JL:2 VAR is not set at all; fi
if [ -z "${VAR}" ];     then echo MP:2 VAR is not set at all; fi
)

输出是:

JL:1 VAR is not set at all
MP:1 VAR is not set at all
MP:2 VAR is not set at all

在第二对测试中,变量设置,但是它被设置为空值。 这就是区别${VAR=value}${VAR:=value}符号做。 同上,用于${VAR-value}${VAR:-value}${VAR+value}${VAR:+value} ,依此类推。


作为吉利在他指出的答案 ,如果您运行bashset -o nounset选项,那么基本的答案上述失败, unbound variable 。 这是很容易纠正:

if [ -z "${VAR+xxx}" ]; then echo VAR is not set at all; fi
if [ -z "${VAR-}" ] && [ "${VAR+xxx}" = "xxx" ]; then echo VAR is set but empty; fi

或者,你可以取消该set -o nounset与选项set +uset -u等同于set -o nounset )。



Answer 2:

~> if [ -z $FOO ]; then echo "EMPTY"; fi
EMPTY
~> FOO=""
~> if [ -z $FOO ]; then echo "EMPTY"; fi
EMPTY
~> FOO="a"
~> if [ -z $FOO ]; then echo "EMPTY"; fi
~> 

-z工程未定义的变量太多。 未定义和区分定义的,你会用列出的东西在这里或者,更清晰的解释, 在这里 。

干净的方式是使用扩大像在这些实施例。 为了让所有的选择检查手册的参数扩展部分。

替代字:

~$ unset FOO
~$ if test ${FOO+defined}; then echo "DEFINED"; fi
~$ FOO=""
~$ if test ${FOO+defined}; then echo "DEFINED"; fi
DEFINED

默认值:

~$ FOO=""
~$ if test "${FOO-default value}" ; then echo "UNDEFINED"; fi
~$ unset FOO
~$ if test "${FOO-default value}" ; then echo "UNDEFINED"; fi
UNDEFINED

当然,你会使用这些不同的一个,把你想要的,而不是“默认值”的值,并直接使用扩展,如果合适的话。



Answer 3:

高级Bash脚本编程指南,10.2。 参数换人:

  • $ {VAR + blahblah}:如果变量被定义, 'blahblah' 被代入表达式,否则返回null是取代
  • $ {VAR-blahblah}:如果VAR的定义,它本身经,否则 'blahblah' 被取代
  • $ {VAR blahblah?}:如果变量被定义,它是取代的,否则该功能与“blahblah”为错误消息的存在。


立足程序逻辑的变量$ myStr中是否定义或没有,你可以做到以下几点:

isdefined=0
${mystr+ export isdefined=1}

现在,如果isdefined = 0,则变量是未定义的,如果isdefined = 1定义的变量

检查变量的这种方式比上面的回答更好,因为它是更优雅,可读的,如果你的bash shell的配置为错误的使用未定义的变量(set -u)该脚本将提前终止。


其他有用的东西:

有分配到$ myStr中,如果它是未定义的7的默认值,并使其保持完好,否则:

mystr=${mystr- 7}

打印的错误信息,并且如果所述变量未定义退出功能:

: ${mystr? not defined}

当心这里,我用“:”以免有作为的情况下,它被定义的命令执行$ myStr中的内容。



Answer 4:

测试总结。

[ -n "$var" ] && echo "var is set and not empty"
[ -z "$var" ] && echo "var is unset or empty"
[ "${var+x}" = "x" ] && echo "var is set"  # may or may not be empty
[ -n "${var+x}" ] && echo "var is set"  # may or may not be empty
[ -z "${var+x}" ] && echo "var is unset"
[ -z "${var-x}" ] && echo "var is set and empty"


Answer 5:

https://stackoverflow.com/a/9824943/14731包含一个更好的答案(一说是更具可读性,并与工作set -o nounset启用)。 它的工作原理大致是这样的:

if [ -n "${VAR-}" ]; then
    echo "VAR is set and is not empty"
elif [ "${VAR+DEFINED_BUT_EMPTY}" = "DEFINED_BUT_EMPTY" ]; then
    echo "VAR is set, but empty"
else
    echo "VAR is not set"
fi


Answer 6:

显式的检查方法定义是一个变量的存在:

[ -v mystr ]


Answer 7:

另一种选择: 在“列表数组的下标”扩展 :

$ unset foo
$ foo=
$ echo ${!foo[*]}
0
$ foo=bar
$ echo ${!foo[*]}
0
$ foo=(bar baz)
$ echo ${!foo[*]}
0 1

这个扩展为空字符串的唯一时间是当foo没有设置,这样你就可以用字符串有条件的检查:

$ unset foo
$ [[ ${!foo[*]} ]]; echo $?
1
$ foo=
$ [[ ${!foo[*]} ]]; echo $?
0
$ foo=bar
$ [[ ${!foo[*]} ]]; echo $?
0
$ foo=(bar baz)
$ [[ ${!foo[*]} ]]; echo $?
0

应该在任何的bash版本是可用> = 3.0



Answer 8:

不要进一步摆脱这种自行车,但想补充

shopt -s -o nounset

是你可以添加到脚本的顶部,如果变量不是在脚本中任何宣布将错误。 你会看到该消息是unbound variable ,但其他人提到它不会赶上一个空字符串或空值。 为了确保任何单个值不为空,因为它与扩大,我们可以测试一个变量${mystr:?}又称美元符号扩展,这将具有错误parameter null or not set



Answer 9:

的击参考手册是约bash的信息的权威来源。

下面是测试一个变量看,如果它存在的一个例子:

if [ -z "$PS1" ]; then
        echo This shell is not interactive
else
        echo This shell is interactive
fi

(从节6.3.2 。)

需要注意的是后开的空白[和前] 不是可选的


提示的Vim用户

我有一个脚本,有几个声明如下:

export VARIABLE_NAME="$SOME_OTHER_VARIABLE/path-part"

但我希望他们推迟到任何现有值。 所以我重新写了他们看起来像这样:

if [ -z "$VARIABLE_NAME" ]; then
        export VARIABLE_NAME="$SOME_OTHER_VARIABLE/path-part"
fi

我能够在使用快速正则表达式VIM自动完成:

s/\vexport ([A-Z_]+)\=("[^"]+")\n/if [ -z "$\1" ]; then\r  export \1=\2\rfi\r/gc

这可以通过肉眼选择相关的行,然后键入应用: 。 命令栏预填充具有:'<,'> 粘贴在上面的命令并回车。


测试在这个版本的Vim:

VIM - Vi IMproved 7.3 (2010 Aug 15, compiled Aug 22 2015 15:38:58)
Compiled by root@apple.com

Windows用户可能需要不同的行尾。



Answer 10:

以下是我认为是来检查变量定义更清晰的方式:

var_defined() {
    local var_name=$1
    set | grep "^${var_name}=" 1>/dev/null
    return $?
}

按如下方式使用它:

if var_defined foo; then
    echo "foo is defined"
else
    echo "foo is not defined"
fi


Answer 11:

呼叫建立不带任何参数..它输出定义的所有瓦尔..
名单上的最后的将是你的脚本中定义的..
所以,你可以管其输出的东西,可以找出事情的定义和什么不



文章来源: How to tell if a string is not defined in a bash shell script?