bash中未设置变量和空变量之间的差异

bash中未设置变量和空变量之间的差异,bash,Bash,使用bash,检查变量是否为空的最佳方法是什么 如果我使用: if [ -z "$VAR" ] 正如论坛中所建议的,这适用于未设置的变量,但当该变量设置为空时则为真。 建议?${var+set}如果变量未设置,则不替换任何内容;如果变量设置为包括空字符串在内的任何内容,则替换为set${var:+set}仅当变量设置为非空字符串时才替换set。您可以使用此选项测试以下任一情况: if [ "${foo+set}" = set ]; then # set, but may be empt

使用bash,检查变量是否为空的最佳方法是什么

如果我使用:

if [ -z "$VAR" ]
正如论坛中所建议的,这适用于未设置的变量,但当该变量设置为空时则为真。
建议?

${var+set}
如果变量未设置,则不替换任何内容;如果变量设置为包括空字符串在内的任何内容,则替换为
set
<代码>${var:+set}仅当变量设置为非空字符串时才替换
set
。您可以使用此选项测试以下任一情况:

if [ "${foo+set}" = set ]; then
    # set, but may be empty
fi

if [ "${foo:+set}" = set ]; then
    # set and nonempty
fi

if [ "${foo-unset}" = unset ]; then
    # foo not set or foo contains the actual string 'unset'
    # to avoid a potential false condition in the latter case,
    # use [ "${foo+set}" != set ] instead
fi

if [ "${foo:-unset}" = unset ]; then
    # foo not set or foo empty or foo contains the actual string 'unset'
fi
这将在变量集列表中搜索字符串“VAR=。

好吧,这里有一种方法

$ s=""
$ declare -p s
declare -- s=""
$ unset s
$ declare -p s
bash: declare: s: not found
如果变量未设置,将出现错误消息

您可以使用

[-v name]


名称没有
$
符号

这仅适用于空,不适用于未设置(或有值)

未设置(不存在)变量和空变量在参数展开中的行为不同:

在以下示例中:
不带冒号

仅检查变量是否存在

带冒号的

检查变量是否存在,如果它存在,请确保它不存在 空的。
换句话说,检查变量的存在性非空性


  • ${参数:-word}

    如果参数为unset或null,则替换word的展开形式。否则,将替换参数的值

  • ${parameter word}

    如果参数未设置


  • ${parameter:=word}

    如果参数是未设置的或空的,则word的展开将指定给参数。然后替换参数的值。位置参数和特殊参数不能以这种方式指定给

  • ${parameter=word}

    如果参数未设置


  • ${参数:?word}

    如果参数为unset或null
    ,则word的扩展(如果word不存在,则会显示相应的消息)将写入标准错误,如果shell不是交互式的,则退出。否则,将替换参数的值

  • ${parameter?word}

    如果参数未设置


  • ${参数:+word}

    如果参数为unset或null,则不替换任何内容,否则替换word的展开形式

  • ${parameter+word}

    如果参数未设置



我不知道是谁投票否决了你,但你的解决方案对我很有效!我第一次回答错了问题。这是一个正确的答案。我的反对票是因为这是一成不变的、笨拙的、低效的。shell为此具有内置功能;此外,您还有一个问题,显然,如果要使用此方法,至少应该将其更改为
If set | grep-q'^VAR=$;然后…
最初的问题是如何区分设置为空字符串的变量和未设置的变量。这两种情况下都返回空白。@KevinBeck,嗯
declare--s=”“
不是空字符串,因此在这种情况下不会“返回空白”;无论如何,您可以检查退出状态:
如果declare-ps&>/dev/null;然后回显“设置了变量s”;else echo“变量s未设置”;fi
。我不反对这一点,因为有更好的选择(更便携,更容易阅读);但它确实有效。为了完善这个答案,您可以添加
-
的工作方式相反,即,
${foo unset}
如果foo未设置,则产生“unset”。这对于干运行脚本非常有用,例如
rsync-avuz${DRYRUN--DRYRUN}$HOME/blog/webserver:blog/
,必须以
DRYRUN=upblog.sh
的形式运行才能实际执行上载。这应该是公认的答案。编辑答案,包括@jcomeau_ictx的精彩评论。这是有史以来最好的事情!在Bash v3.2.57(1)或v4.1.5(1)中都找不到这一点。这是哪个shell?我的bashshell版本是ubuntu 15.10中的4.3。使用“帮助测试”命令检查“-v”运算符是否存在。实际上有两个测试命令,一个是shell内置命令,另一个是/usr/bin/test。由于POSIX不支持
-v
,请使用
[…]
而不是
[…]
。欢迎使用stackoverflow。请详细阐述一下这种方法是如何工作的,而不是公认的答案。这只是个问题。它需要在扩展名周围加上引号,并在结尾处加上一个“
]”
(或将“
[
更改为“
测试”
”)才能正常工作。
$ s=""
$ declare -p s
declare -- s=""
$ unset s
$ declare -p s
bash: declare: s: not found
[ -z ${VAR-X}