【问题标题】:difference between unset and empty variables in bashbash中未设置变量和空变量之间的区别
【发布时间】:2020-09-09 01:45:15
【问题描述】:

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

如果我使用:

if [ -z "$VAR" ]

正如论坛中所建议的,这适用于未设置的变量,但当变量已设置但为空时,它是正确的。 有什么建议吗?

【问题讨论】:

    标签: bash


    【解决方案1】:

    ${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
    

    【讨论】:

    • 只是为了完善这个答案,您可能会补充说- 以相反的方式工作,即如果 foo 未设置,${foo-unset} 会产生“未设置”。这对于空运行脚本很有用,例如rsync -avuz ${DRYRUN---dry-run} $HOME/blog/ webserver:blog/ 必须以 DRYRUN= upblog.sh 运行才能实际执行上传。
    • 这应该是公认的答案。编辑后的答案包括 @jcomeau_ictx 的出色评论。
    • 这是有史以来最好的事情!你应该得到 10000 个赞 @geekosaur
    【解决方案2】:

    你可以用

    测试

    [ -v name ]

    名称没有$ 符号

    【讨论】:

    • 我在 Bash v3.2.57(1) 或 v4.1.5(1) 中都找不到这个。这是哪个外壳?
    • 我的 bash shell 版本在 ubuntu 15.10 中是 4.3。使用“help test”命令检查是否存在“-v”运算符。实际上有两个测试命令一个是shell内置的,另一个是/usr/bin/test
    • 由于 POSIX 不支持-v,所以使用[[ ... ]] 而不是[...]
    【解决方案3】:

    未设置(不存在)的变量和空变量在参数扩展中表现不同:

    在以下示例中:
    没有冒号

    仅检查变量是否存在

    带冒号

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


    • ${parameter:-word}
      如果参数为unset 或null,则替换单词的扩展。否则,参数的值被替换。

    • ${parameter-word}
      如果参数是未设置...


    • ${parameter:=word}
      如果 parameter 为 unset 或 null,则将 word 的扩展分配给 parameter。然后替换参数的值。位置参数和特殊参数不能这样赋值。

    • ${parameter=word}
      如果参数是未设置...


    • ${parameter:?word}
      如果参数是 unset 或 null,则 word 的扩展(或如果 word 不存在,则将显示该效果的消息)写入标准错误和 shell,如果它不是交互式的,退出。否则,参数的值被替换。

    • ${parameter?word}
      如果参数是未设置...


    • ${parameter:+word}
      如果参数为unset 或null,则不替换,否则替换单词的扩展。

    • ${parameter+word}
      如果参数是未设置...


    Source

    【讨论】:

      【解决方案4】:

      好吧,这是一种方法

      $ s=""
      $ declare -p s
      declare -- s=""
      $ unset s
      $ declare -p s
      bash: declare: s: not found
      

      如果未设置变量,则会出现错误消息。

      【讨论】:

      • 最初的问题是如何区分设置为空字符串的变量与根本没有设置的变量。这两种情况都返回空白。
      • @KevinBeck,嗯? declare -- s="" 不是空字符串,因此在这种情况下它不会“返回空白”;无论如何,您只需检查退出状态:if declare -p s &>/dev/null; then echo "Variable s is set"; else echo "Variable s is unset"; fi。我不赞成这一点,因为有更好的选择(更便携,更易于阅读);但它确实工作
      【解决方案5】:
      if [ `set | grep '^VAR=$'` ]
      

      这会在变量集列表中搜索字符串“VAR=”。

      【讨论】:

      • 我不知道谁投票给你,但你的解决方案对我有用!
      • 我第一次回答错了问题。这是一个更正的答案。
      • 我的反对意见是因为这是单调、笨拙和低效的。外壳为此具有内置功能;此外,你有一个useless use of backticks 显然是an incomplete understanding of what the if statement does.
      • 如果要使用这种方式,至少应该改成if set | grep -q '^VAR=$'; then ...
      【解决方案6】:

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

      [ -z ${VAR-X}
      

      【讨论】:

      • 欢迎来到stackoverflow。请详细说明这种方法的工作原理,而不是接受的答案。
      • 这简直是错误的。它需要在扩展和结束 ](或从 [test 的更改)周围加上引号才能正常运行。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-30
      • 1970-01-01
      • 2011-05-25
      • 2016-03-22
      • 1970-01-01
      相关资源
      最近更新 更多