我希望在我的bash脚本中使用以下变量,但如果这是空的或null,那么处理它并从脚本退出的最佳方法是什么。
tag=$1
我看到'set -u'的答案。我知道这会有效,但这对生产环境有好处吗?
答案 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