【问题标题】:Shell script - exiting script if variable is null or emptyShell 脚本 - 如果变量为空或为空,则退出脚本
【发布时间】:2015-07-01 14:32:11
【问题描述】:

我希望在我的 bash 脚本中使用以下变量,但如果它为空或 null,那么处理它并退出脚本的最佳方法是什么。

tag=$1  

我看到了“set -u”的答案。我知道这会起作用,但这对生产环境有好处吗?

【问题讨论】:

  • 是否应该将仅由空格组成的变量像这样:var=" " 视为空?
  • 是的,由空格组成的变量,被认为是空的。基本上,我想检查一下 if [[ ! -z "${Tag}" && "${Tag}" != '' ]] 对于这个。

标签: linux bash shell unix


【解决方案1】:

如果你想测试一个变量是否为非空,你可以这样做:

if [ -z "$tag" ]; then
    exit 1
fi

来自test的手册:

-z 字符串

STRING的长度为零

鉴于您正在使用脚本的位置参数,您还可以通过查看 $# 来测试收到的参数数量。

【讨论】:

  • 您需要在"$tag" 周围加上引号,否则在空字符串上会失败(试试看)。
【解决方案2】:

有一个内置运算符要求设置变量。如果不是,这将导致脚本退出。

tag=${1?Need a value}

这通常与脚本开头附近的: no-op 一起使用。

: ${1?Need a value}

“未设置或为空”的混淆有些不同。没有类似的结构可以退出一个空但设置的值,但是您可以轻松地使用相关的语法${var:-default},如果它已设置且非空,则扩展为$var,否则扩展为default。还有 ${var-default} 仅在变量未正确设置时才产生 default

当您想要使用set -u但需要处理可能未设置的变量时,这可能特别有用:

case ${var-} in '') echo "$0: Need a value in var" >&2; exit 1;; esac

我在某种程度上更喜欢case 而不是if [ "${var-}" = '' ],主要是因为它使我不必在${var-} 周围加上双引号,以及$var 中的值的讨厌情况,它被解释为@987654335 的一个选项@ 并在您最不期望的时候给您一条错误消息。 (在 Bash 中,[[ 没有这些问题;但我更愿意尽可能坚持使用 POSIX shell。)

【讨论】:

    【解决方案3】:

    使用模式匹配来检测值是否仅包含空格:

    pattern=$'*( |\t)'
    if [[ $1 = $pattern ]]; then
        echo "First parameter has no non-whitespace characters"
        exit 1
    fi
    

    $'...' 引用使在字符串中添加制表符变得更加容易。扩展模式 *(...) 匹配 0 个或多个括号内的模式(类似于正则表达式 ( |\t)*)。该模式被分配给一个变量,因为= 会在其右侧操作数的任何部分被引用时执行精确的字符串匹配,因此我们预先执行引用以更容易设置值。

    【讨论】:

    • 您需要启用扩展通配才能使其工作,不是吗?
    • 也许吧。 bash 的较新版本(4.2 和更高版本?)暂时在 [[... ]] 内部打开扩展通配符,因此无需明确这样做。否则,是的,需要shopt -s extglob
    【解决方案4】:

    我不确定您是否要检测变量是unset 还是empty。这是2个不同的东西。具体来说,可以设置一个变量但为空:

    $ var=""
    $ if [ -z "$var" ]; then echo empty; fi
    $ empty
    

    这里也是如此:

    #!/usr/bin/env bash
    
    set -u
    echo $1
    

    测试:

    $ ./test.sh
    ./test.sh: line 4: $1: unbound variable
    $ ./test.sh ""
    
    $
    

    或者这里:

    #!/usr/bin/env bash
    
    tag=${1?Need a value}
    echo $tag
    

    测试:

    $ ./se.sh
    ./se.sh: line 3: 1: Need a value
    $ ./se.sh ""
    
    $
    

    其他海报展示了检测未设置和空变量的正确方法。我个人喜欢这种检测空变量和未设置变量的方法:

    #!/usr/bin/env bash
    
    if [ "$1"A = A ]
    then
        echo variable is empty or unset
    fi
    

    测试:

    $ ./empty.sh ""
    variable is empty or unset
    $ ./empty.sh
    variable is empty or unset
    $ ./empty.sh 1
    $
    

    【讨论】:

    • "$1"A 方法在任何远程现代 shell 实现中都是不必要的。对于无法处理 test 命令的显式空参数的旧 shell,这是必要的 hack。 [ "$1" = "" ] 也可以处理空/未设置的 $1
    • 没必要,但我还是喜欢。这是个人喜好的问题。
    【解决方案5】:

    没有人建议:? 选项。

    如果要确保变量已设置且不为空:

    SEARCH_PATH=${DAYS_TO_KEEP:?Must provide DAYS_TO_KEEP.}
    

    将使用代码 2 立即退出并打印一条消息:

    /entrypoint.sh: line 17: SEARCH_PATH: Must provide DAYS_TO_KEEP.
    

    【讨论】:

    • 这在 Ubuntu 上以 1 退出。另外,这与 Tripleee 接受的答案有什么区别?
    • 如上所述,用户可以使用不同的选项来确保变量存在且不为空。
    • 所以这里唯一的区别是你的也检查空值?并且接受的答案不检查是否为空?这真是太棒了!我会让这种区别更清楚(在你的回答中),以便更强烈地将你的区别与接受的区别:slightly_smiling_face:
    【解决方案6】:

    我更喜欢 Perl 使用“die”的方式,并且在 shell 中很容易做类似的事情。

    # Print (optional) error message and exit
    # Usage: die [[msg] exit_status]
    die() {
        [[ -n "$1" ]] && echo "$1"
        [[ -n "$2" ]] && exit $2 || exit 1
    }
    
    [[ -n "$tag" ]] || die "Need a tag argument.  Use $0 --help for details"
    

    这假定使用 bash 或 Korn shell,但可以通过将 [[]] 更改为 [] 来转换为经典的 Bourne shell。

    【讨论】:

      【解决方案7】:

      以下测试确保变量为 Null 或已分配值。双引号非常重要,必须使用!

      VAL= # Creates a NULL variable
      if [[ -z "$VAL" && "$VAL" = ’’ ]]
      then
      echo "The VAL variable is NULL"
      fi
      or
      VAL=25
      if [[ ! -z "$VAL" && "$VAL" != ’’ ]]
      then
      echo "The VAL variable is NOT NULL"
      fi
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-11-14
        • 2013-02-04
        • 2021-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-25
        • 1970-01-01
        相关资源
        最近更新 更多