当前位置:  开发笔记 > 编程语言 > 正文

如何判断字符串是否未在bash shell脚本中定义?

如何解决《如何判断字符串是否未在bashshell脚本中定义?》经验,为你挑选了5个好方法。

如果我想检查空字符串,我会这样做

[ -z $mystr ]

但是,如果我想检查变量是否已定义呢?或者bash脚本没有区别?



1> Jonathan Lef..:

我认为你所追求的答案是由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' 结合使用,并建议使用单独的简单测试&&.我没遇到过有问题的系统; 这并不意味着它们过去不存在(但它们现在可能极为罕见,即使它们在遥远的过去并不罕见).

您可以在Bash手册中找到这些的详细信息,以及其他相关的shell参数扩展,test[命令和条件表达式.


我最近通过电子邮件询问了这个问题:

你使用两个测试,我理解第二个,但不是第一个.更确切地说,我不了解变量扩展的必要性

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},等等.


正如Gili在他的回答中指出的那样,如果你bash使用该set -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 +u(set -u相当于set -o nounset).


我对这个答案唯一的问题是它以一种相当间接和不明确的方式完成它的任务.
对于那些想要在bash手册页中查找上述内容的描述的人,请查找"参数扩展"部分,然后查找本文:"当不执行子串扩展时,使用下面记录的表单,bash测试一个未设置的参数或null ['null'表示空字符串].省略冒号只会导致对未设置的参数进行测试(...)$ {parameter:+ word}:使用Alternate Value.如果参数是null或未设置,没有替代,否则单词的扩展被替换."
@Swiss这既不明确也不间接,但不是惯用的.也许对于不熟悉`$ {+}`和`$ { - }`的程序员来说,目前还不清楚,但如果要成为shell的合格用户,那么熟悉这些结构是必不可少的.

2> Vinko Vrsalo..:
~> 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

当然,您可以使用其中一种方法,将所需值设置为"默认值"并直接使用扩展(如果适用).


在bash手册页中查找所有这些"技巧"的"参数扩展".例如$ {foo:-default}使用默认值$ {foo:= default}来分配默认值$ {foo:?error message}以在foo未设置时显示错误消息等.

3> 小智..:

高级bash脚本编写指南,10.2.参数替换:

$ {var + blahblah}:如果定义了var,则用'blahblah'代替表达式,否则替换为null

$ {var-blahblah}:如果var被定义,它本身被替换,否则'blahblah'被替换

$ {var?blahblah}:如果定义了var,则替换它,否则该函数以'blahblah'作为错误消息存在.


根据是否定义了变量$ mystr来编写程序逻辑,可以执行以下操作:

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

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

这种检查变量的方法比上面的答案要好,因为它更优雅,可读,并且如果你的bash shell配置为使用未定义的变量时出错(set -u),脚本将过早终止.


其他有用的东西:

如果未定义,则将默认值7分配给$ mystr,否则保持原样:

mystr=${mystr- 7}

如果变量未定义,则打印错误消息并退出函数:

: ${mystr? not defined}

请注意,我使用':'以便在定义时不将$ mystr的内容作为命令执行.



4> k107..:

测试摘要.

[ -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"



5> Gili..:

/sf/ask/17360801/包含一个更好的答案(一个更具可读性且适用于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

推荐阅读
ifx0448363
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有