Bash如何判断变量是否为空,如果是则退出。

39

我正在尝试执行以下操作: 我有一个测试文件,其中包含位于sftp上的文件的md5sum。 变量应该包含一个md5sum(字符串),如果变量为空,则表示在sftp服务器上没有文件。 我正在尝试这段代码,但它不起作用...

    if [ -z $I_IDOCMD5 ] || [ -z $I_LEGALMD5 ] || [ -z $I_ZIPMD5 ]
then
        echo "ERROR: At least one file not present of checksum missing no files will be deleted" >>$IN_LOG
        ERRORS=$ERRORS+2
else
 if [[ $I_IDOCMD5 == $($DIGEST -a md5 $SAPFOLDER/inward/idoc/$I_IDOC) ]]
   then
        echo "rm IDOC/$I_IDOC" >/SAP/commands_sftp.in
   else
        echo "problem with checksum"
        ERRORS=$ERRORS+2
 fi

 if [[ $I_LEGALMD5 == $($DIGEST -a md5 $SAPFOLDER/inward/legal/$I_LEGAL) ]]
   then
        echo "rm LEGAL/$I_LEGAL" >>/SAP/commands_sftp.in
   else
        echo "problem with checksum"
        ERRORS=$ERRORS+2
 fi

 if [[ $I_ZIPMD5 == $($DIGEST -a md5 $SAPFOLDER/inward/zip/$I_ZIP) ]]
   then
        echo "rm ZIP/$I_ZIP" >>/SAP/commands_sftp.in
   else
        echo "problem with checksum"
        ERRORS=$ERRORS+2
fi

4
“it doesn't work” 意思是什么?你得到了什么结果?你期望得到什么结果?请解释。 - gniourf_gniourf
将您的变量用双引号括起来。如果不这样做,空格(或更糟)可能会成为一个致命问题。 - thom
可能与此无关,但请检查是否有遗漏了“fi”语句的地方。 - thom
你好,谢谢。我的意思是,即使有一个变量为空,它仍然会执行所有的MD5验证。如果至少有一个变量为空,我希望它跳过所有的MD5验证。 - user2653557
6个回答

66

我更倾向于以下答案。

[[ -z "$1" ]] && { echo "Parameter 1 is empty" ; exit 1; }

注意,在每个指令后面的 {} 中不要忘记加上 ;


30

检查变量是否为空的一种方法是:

if [ "$var" = "" ]; then
    # $var is empty
fi

另一个更短的替代方案是这样的:

[ "$var" ] || # var is empty

1
“x"$var" = x” 的技巧只适用于古老的、有缺陷的 Bourne shell 版本。今天使用 “[ "$var" = "" ]” 就足够了。 - chepner

11
在bash中,您可以使用set -u,这会导致bash在参数扩展失败时退出。
从bash man(关于set内置的部分):

-u
当执行参数扩展时,将未设置的变量和参数(除了特殊参数“@”和“*”)视为错误。如果尝试在未设置的变量或参数上扩展,则shell会打印一条错误消息,并且如果不是交互式的,则以非零状态退出。

更多信息,请参阅此文章: http://redsymbol.net/articles/unofficial-bash-strict-mode/

1
-u只能检测变量是否未设置,而不能检测其是否为空。 - Miguel Sánchez Villafán

4
您可以使用简短的表单:

FNAME="$I_IDOCMD5"
: ${FNAME:="$I_LEGALMD5"}
: ${FNAME:="$I_ZIPMD5"}
: ${FNAME:?"Usage: $0 filename"}

在这种情况下,如果没有声明I_...变量之一,脚本将退出,并打印一个错误消息,该消息以触发消息的shell脚本行为前缀。
更多信息请参见abs-guide(搜索“Example 10-7”)。

3

首先只测试这个(仅为缩小范围):

if [ -z "$I_IDOCMD5" ] || [ -z "$I_LEGALMD5" ] || [ -z "$I_ZIPMD5" ]
then
    echo "one is missing"
else
    echo "everything OK"
fi

echo "\"$I_IDOCMD5\""
echo "\"$I_LEGALMD5\""
echo "\"$I_ZIPMD5\""

它本身似乎可以工作...但在实际脚本中,它会同时执行结束和否定。 如果我采取上面的测试,它将显示“一个缺失”,但也会显示“一切正常”。 - user2653557
也许是因为你最后的 if 块没有用 fi 闭合?在末尾添加一个额外的 fi。提示:扩展你的缩进。 - thom
我承认我运行了你的脚本(使用模拟变量),但它因为一个错误而失败了。我进行了修正,现在它可以正常运行了。 - thom

0

"如果变量为空,意味着SFTP服务器上没有文件"

如果SFTP服务器上没有文件,那么变量真的是空的吗?

没有隐藏的空格或其他任何内容?或者数字零(计为非空)?


你好,它是空的,我已经去掉了所有的空格。但是现在你提到了它,这个值可以是0...如果这个值是0(整数0或者它是空的(没有隐藏的空格))。 - user2653557
整数0如果被解释为字符串(字符串不为空),则无法通过-z测试。您可以使用其他答案中提到的代码进行测试。 - thom

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