如何在Bash中查找变量是否为空

347

如何在Bash中检查变量是否为空?


1
http://serverfault.com/questions/7503/how-to-determine-if-a-bash-variable-is-empty - Ciro Santilli OurBigBook.com
可能是如何在Bash中检查变量是否设置?的重复。 - codeforester
1
在Bash中测试非零长度字符串的方法:-n“$var” vs“$var”。中的真/假表格,@codeforester指出这个表格是绝对精彩的,它展示了如何使用-n-z(它们的上下文)真正有所不同,并且在Shell脚本语言中,有许多(看似微妙的)陷阱需要注意。 - Zach Young
你好@codeforester,日期显示这是较早的问题。另一个是重复的。 - undefined
11个回答

517
在Bash中,至少以下命令可以测试$var是否为空: if [ -z "$var" ]
if [[ -z "$var" ]]; then
   # $var is empty, do what you want
fi

命令man test是你的好朋友。


77
双方括号在这里是无用的。可以简单地使用 [ -z "$var" ] ,甚至更容易,如果使用 test -z "var" .. 无论如何 +1 :) - Luca Borrione
2
双方括号并不是无用的,如果我不包含它们,我会得到./test.ksh[8]: test: argument expected的错误提示。虽然我不知道原因,但单个方括号没有起作用,而双方括号却可以。 - gahlot.jaggs
12
@LucaBorrione 我想你的意思是 if test -z "$var",对吗? - neu242
1
仅针对问题中未直接提及的特定情况添加一条注释:如果变量未设置并且已启用set -u选项,则此测试将以“未定义变量”错误失败。在这种情况下,你可能更喜欢@alexli的解决方案。 - anol
3
作为一个晚期的补充说明:"[[" 可以被视为“永远不会无用的”; 因为使用 "[[" 比 "[" 有一些优点(例如,请参见https://dev59.com/NXRB5IYBdhLWcg3wSVi1) - GhostCat
显示剩余5条评论

159

假设使用Bash:

var=""
if [ -n "$var" ]; then
    echo "not empty"
else
    echo "empty"
fi

18
更直接的答案是 -z[[ -z "$an_unset_or_empty_var" ]] && echo empty - glenn jackman
4
@glenn jackman的评论很好,他说-z更接近于所要求的。Jay在他的回答中已经提到了这一点,所以我不会更新我的回答,将其保留如原样。 - ChristopheD
10
请注意,-z 表示零长度字符串,而 -n 表示非零长度字符串。参考:https://www.gnu.org/software/bash/manual/html_node/Bash-Conditional-Expressions.html - Abel Wenning

56

2
这看起来对我来说很奇怪。你能解释一下这个解决方案吗?谢谢。 - guettli
3
@guettli:如果 $variable 是空的,则比较运算符左侧的字符串仅变成 x,然后等于运算符右侧的字符串。[ x = x ]是“真”,因此实际上测试了$variable是否为空。作为补充(三年半之后:-)),我永远不会使用这个方法,因为-z以更清晰的方式完成我想要的操作,但我想添加这个答案,因为这种方法经常在“野外”中看到;也许写成这样的人有着不同于我的经验。 - Daniel Andersson
1
由于这种方法经常在实践中出现;通常在configure脚本中看到,它可以与sh一起使用,以及任何可能没有-z标志的非标准bash。当存在许多不同微小细节上彼此不兼容的Unix版本(如支持-z标志)时,这种情况通常会发生。现在Linux已经取代了它,这不是什么问题(除非你在一个古老而有趣的Unix系统上)。 - Linas

39
if [ ${foo:+1} ]
then
    echo "yes"
fi

如果变量已设置,则打印yes。当变量已设置时,${foo:+1}将返回1,否则将返回空字符串。


5
虽然问题中没有提到,但这个答案的一个重要优点是,即使变量未定义并且激活了set -u选项(nounset),它仍然起作用。几乎所有其他回答在这种情况下都将因为unbound variable而失败。 - anol
这个 :+ 符号也适用于你已经使用可选变量指定的可选命令行参数的情况。myprogram ${INFILE:+--in=$INFILE} ${OUTFILE:+--out=$OUTFILE} - Alan Porter

12
[ "$variable" ] || echo empty
: ${variable="value_to_set_if_unset"}

很好的方法来将变量默认为1。 - ehime
1
@ehime 如果要设置默认值,您可以使用${variable:-default_value} - warvariuc
这是一种快速检查变量输入有效性并在未设置时退出的方法: [ "$variable" ] || exit - Marcel Sonderegger
你的第一行是对bash脚本中track=${1:?"必须在第一个参数位置提供一个跟踪号,例如 't41'。"}的重新实现。你的第二行在bash中无效;也许你的意思是 : ${variable:="如果未设置则要设置的值"}。请参阅https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html - Cliff
你的第一行是bash的重新实现,track=${1:?"必须将跟踪号作为第一个参数,例如't41'"}。你的第二行在bash中不起作用;也许你的意思是 : ${variable:="如果未设置则设置的值"}。请参考https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html。 - undefined

11

这个问题询问如何检查一个变量是否为空字符串,最佳答案已经给出。

但是我在编写PHP程序后过了一段时间才来到这里,实际上我正在搜索类似于Bash shell中的empty函数的检查方法。

阅读答案后我意识到我在Bash中没有正确地思考,但无论如何,在那个时刻,像PHP中的empty函数那样的功能将会非常方便。

因为我认为这种情况可能会发生在其他人身上,所以我决定在Bash中转换PHP empty函数。

根据PHP手册

如果变量不存在或其值为以下内容之一,则将该变量视为空:

  • ""(空字符串)
  • 0(作为整数的0)
  • 0.0(作为浮点数的0)
  • "0"(作为字符串的0)
  • 一个空数组
  • 已声明但没有值的变量

当然,nullfalse情况无法在bash中转换,因此它们被省略。

function empty
{
    local var="$1"

    # Return true if:
    # 1.    var is a null string ("" as empty string)
    # 2.    a non set variable is passed
    # 3.    a declared variable or array but without a value is passed
    # 4.    an empty array is passed
    if test -z "$var"
    then
        [[ $( echo "1" ) ]]
        return

    # Return true if var is zero (0 as an integer or "0" as a string)
    elif [ "$var" == 0 2> /dev/null ]
    then
        [[ $( echo "1" ) ]]
        return

    # Return true if var is 0.0 (0 as a float)
    elif [ "$var" == 0.0 2> /dev/null ]
    then
        [[ $( echo "1" ) ]]
        return
    fi

    [[ $( echo "" ) ]]
}
示例用法:
if empty "${var}"
    then
        echo "empty"
    else
        echo "not empty"
fi



示例:
以下代码片段:

#!/bin/bash

vars=(
    ""
    0
    0.0
    "0"
    1
    "string"
    " "
)

for (( i=0; i<${#vars[@]}; i++ ))
do
    var="${vars[$i]}"

    if empty "${var}"
        then
            what="empty"
        else
            what="not empty"
    fi
    echo "VAR \"$var\" is $what"
done

exit

输出:

VAR "" is empty
VAR "0" is empty
VAR "0.0" is empty
VAR "0" is empty
VAR "1" is not empty
VAR "string" is not empty
VAR " " is not empty

尽管如此,在Bash逻辑中,此函数中对零的检查可能会导致副作用问题。我认为,任何使用此函数的人都应该评估这种风险,并可能决定删掉那些检查,只留下第一个检查。


11
if [[ "$variable" == "" ]] ...

9

如果变量未设置或设置为空字符串(""),则此函数将返回true

if [ -z "$MyVar" ]
then
   echo "The variable MyVar has nothing in it."
elif ! [ -z "$MyVar" ]
then
   echo "The variable MyVar has something in it."
fi

5
为什么要使用 elif ! 而不是 else - ZiggyTheHamster
1
为了区分这两个语句,即使用 ! [ -z "$MyVar" ] 将意味着变量 已经 有一些内容。但理想情况下应该使用 else - 3kstc

4
您可能想区分未设置的变量和已设置为空的变量:
is_empty() {
    local var_name="$1"
    local var_value="${!var_name}"
    if [[ -v "$var_name" ]]; then
       if [[ -n "$var_value" ]]; then
         echo "set and non-empty"
       else
         echo "set and empty"
       fi
    else
       echo "unset"
    fi
}

str="foo"
empty=""
is_empty str
is_empty empty
is_empty none

结果:

set and non-empty
set and empty
unset

顺便说一下,我建议使用set -u命令,它会在读取未设置的变量时引发错误,这可以避免诸如此类的灾难。
rm -rf $dir

您可以在此处阅读有关“严格模式”的最佳实践和其他信息:这里

感谢提供严格模式的参考! - paulcm

1

检查变量v是否未设置

if [ "$v" == "" ]; then
   echo "v not set"
fi

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