BASH脚本对于两者都返回,但相反的字符串测试



在我运行脚本之前,我已经输入了

# export CPIC_MAX_CONV=500

以下是test1.script文件

#!/bin/bash
function cpic () {
  var="`export | grep -i "CPIC_MAX_CONV" | awk '/CPIC_MAX_CONV/ { print $NF } '`"
  [[ $var=="" ]] && (echo "Empty String <<")
  [[ $var!="" ]] && (echo "$CPIC_MAX_CONV")
  echo "$var" ;
}
cpic

输出为:

# test1.script  ---- Me running the file
Empty String <<
500
CPIC_MAX_CONV="500"

不管我使用什么"或"或[[[结果是相同的。CPIC_MAX_CONV变量是通过上述脚本找到的。

我在Linux/CentOS 6.3上运行此操作。

这个想法很简单:查找是否在环境中定义了CPIC_MAX_CONV并返回其值。如果存在空白空间,则当然在系统中不存在变量。

为什么您总是真正成真?让我们首先在您的终端中玩一点:

$ [[ hello ]] && echo "True"

您认为输出是什么?(尝试!)以及以下内容?

$ [[ "" ]] && echo "True"

(尝试!)。

好吧,因此似乎非空字符串等同于真实表达式,而一个空字符串(或一个不设置变量)等同于false表达式。

您所做的就是以下内容:

[[ $var=="" ]]

[[ $var!="" ]]

所以您给了一个非空字符串,这是真的!

为了执行测试,您实际上需要令牌之间的空间:

[[ $var == "" ]]

而是。现在,您的测试将更好地写为:

if [[ -z "$var" ]]; then
    echo "Empty String <<"
else
    echo "$CPIC_MAX_CONV"
fi

(没有子壳,只有一个测试)。

关于您的脚本风格还有更多话要说。没有冒犯,我会说这真的很糟糕:

  • 不要使用回头!改用$(...)构造。因此:

    var="$(export | grep -i "CPIC_MAX_CONV" | awk '/CPIC_MAX_CONV/ { print $NF } ')"
    
  • 不要使用function blah来定义功能。您的功能应该定义为:

    cpic () {
        local var="$(export | grep -i "CPIC_MAX_CONV" | awk '/CPIC_MAX_CONV/ { print $NF } ')"
        if [[ -z "$var" ]]; then
            echo "Empty String <<"
        else
            echo "$CPIC_MAX_CONV"
        fi
    }
    

哦,我使用了local关键字,因为我想您不会在函数cpic之外使用变量var

现在,函数cpic的目的是什么,特别是您定义变量var的内容的目的是什么?很难描述(因为有很多您没有想到的情况)。(顺便说一句,您的grep似乎在这里确实没有用)。以下是您忽略的几种情况:

  • 导出变量命名为 somethingfunnyCPIC_MAX_CONVsomethingevenfunnier
  • 导出的变量包含字符串CPIC_MAX_CONV,例如,

    export a_cool_variable="I want to screw up Randhawa's script and just for that, let's write CPIC_MAX_CONV somewhere here"
    

好吧,我不想描述您的行确实在做什么,但是我猜想您的目的是知道是否设置了变量CPIC_MAX_CONV并标记为导出,对吗?在这种情况下,您会更好地:

cpic () {
    if declare -x | grep -q '^declare -x CPIC_MAX_CONV='; then
        echo "Empty String <<"
    else
        echo "$CPIC_MAX_CONV"
    fi
}

它将更有效,而且更强大。

哦,我现在只是在阅读您帖子的结尾。如果您只想知道是否设置了可变CPIC_MAX_CONV(对于某些非空价值 - 似乎您不在乎它是否标记为导出,请纠正我,如果我错了),这甚至更简单(它将提高得多):

cpic () {
    if [[ "$CPIC_MAX_CONV" ]]; then
        echo "Empty String <<"
    else
        echo "$CPIC_MAX_CONV"
    fi
}

也会做!

您真的在乎CPIC_MAX_CONV是否是环境变量,而只是'它是一个可能是环境变量的变量'?最有可能的是,您不会,尤其是因为它是变量但不是一个环境变量,您运行的任何脚本都不会看到该值(但是如果您坚持使用别名和功能可能不会)。

似乎您正在尝试测试CPIC_MAX_CONV是否设置为非空值。有多种简单的方法可以做到这一点 - 然后是您尝试的方法。

: ${CPIC_MAX_CONV:=500}

这确保CPIC_MAX_CONV设置为非空值;如果以前没有值集,则使用500。:(COLON)命令评估其参数并报告成功。如果要使用export CPIC_MAX_CONV

如果您必须具有变量集(没有合适的默认值),则使用:

: ${CPIC_MAX_CONV:?}

: ${CPIC_MAX_CONV:?'The CPIC_MAX_CONV variable is not set but must be set'}

区别在于您可以使用默认消息('cpic_max_conv:parameter null或不设置')或指定自己的。

如果您只想使用一次值,则可以在命令中进行"飞行"替换:

cpic_command -c ${CPIC_MAX_CONV:-500} ...

这不会创建变量,如果它不存在,与:=表示法不同。

在所有这些符号中,我一直使用结肠作为手术的一部分。强制执行" null或不设置";您可以省略结肠,但这允许一个空字符串作为有效的值,这可能不是您想要的。请注意,仅由空白组成的字符串是"不空"。如果您需要验证自己有一个非空字符串,则必须更加努力。


我没有解剖您对[[命令的滥用;gniourf_gniourf提供了对此的极好的解构,但忽略了可以做似乎是工作的简单符号。

尝试以下:

#!/bin/bash
function cpic () {    
  var="`export | grep -i "CPIC_MAX_CONV"`"
  [ "$var" = "" ] && (echo "Empty String <<")
  [ "$var" != "" ] && echo "$CPIC_MAX_CONV"
}  
cpic

您需要在条件下的空间。

#!/bin/bash
function cpic () {
    var="`export | grep -i "CPIC_MAX_CONV" | awk '/CPIC_MAX_CONV/ { print $NF } '`"
    [[ $var == "" ]] && (echo "Empty String <<")
    [[ $var != "" ]] && (echo "$CPIC_MAX_CONV")
    echo "$var" ;
}
cpic

最新更新