Shell脚本 - 如果变量为null或为空,则退出脚本

时间:2015-07-01 14:32:12

标签: linux bash shell unix

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

tag=$1  

我看到'set -u'的答案。我知道这会有效,但这对生产环境有好处吗?

7 个答案:

答案 0 :(得分:26)

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

tag=${1?Need a value}

通常,这与脚本开头附近的:无操作一起使用。

: ${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中包含值的令人讨厌的情况被解释为[的一个选项,并在您最不期望的时候给出错误消息。 (在Bash中,[[没有这些问题;但我更愿意坚持使用POSIX shell。)

答案 1 :(得分:15)

如果要测试变量是非空的,可以这样做:

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

来自test的手册:

  

-z STRING

     

STRING的长度为零

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

答案 2 :(得分:5)

没有人建议使用:?选项。

如果要确保设置了变量且不为null:

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

将立即以代码2退出并显示一条消息:

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

答案 3 :(得分:3)

我不确定您是否要检测变量是unset还是empty。这是两件不同的事情。具体来说,可以设置变量但是为空:

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

答案 4 :(得分:1)

我更喜欢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。

答案 5 :(得分:0)

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

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

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

答案 6 :(得分:0)

以下测试确保变量为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