我希望在我的bash脚本中使用下面的变量,但是如果它为空或为null,最好的处理方式是什么,如何退出脚本。
tag=$1
我看到一些答案中使用了 'set -u'。我知道这样做可以运行,但这对于生产环境是否好呢?
有一个内置的运算符,可以要求设置变量。如果变量没有被设置,脚本将退出。
tag=${1?Need a value}
通常这与脚本开头的:
no-op一起使用。
: ${1?Need a value}
"unset or empty"的合并有所不同。没有类似的结构可以在空但已设置的值上退出,但您可以轻松使用相关语法${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。)
如果您想测试一个变量是否为非空值,您可以这样做:
if [ -z "$tag" ]; then
exit 1
fi
从test
的手册中得知:
-z STRING
STRING长度为零
如果您正在使用脚本的位置参数,您还可以通过查看$#
来测试接收到的参数数量。
"$tag"
周围加上引号,否则在空字符串上会失败(试一下就知道)。 - Etan Reisner:?
选项。SEARCH_PATH=${DAYS_TO_KEEP:?Must provide DAYS_TO_KEEP.}
将立即以2的代码退出并打印一条消息:
/entrypoint.sh: line 17: SEARCH_PATH: Must provide DAYS_TO_KEEP.
1
退出。另外,这与tripleee的已接受答案有什么区别? - derpedy-doo我不确定您想检测变量是否未设置还是为空。这两个是不同的。具体而言,一个变量可以被设置但为空:
$ 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 实现中都是不必要的。这是一个 hack,旧的 shell 无法处理 test
命令的显式空参数。[ "$1" = "" ]
同样可以很好地处理空/未设置的 $1
。 - chepnerpattern=$'*( |\t)'
if [[ $1 = $pattern ]]; then
echo "First parameter has no non-whitespace characters"
exit 1
fi
$'...'
的引用使字符串中添加制表符更加容易。扩展模式 *(...)
匹配圆括号内的模式0次或多次(类似于正则表达式 ( |\t)*
)。将模式分配给变量,因为如果右操作数的任何部分被引用,=
执行精确字符串匹配,因此我们事先进行引用以便更轻松地设置该值。bash
(4.2 及以后?)中,暂时会在 [[... ]]
内部打开扩展通配符,因此无需显式地执行此操作。否则,是的,需要使用 shopt -s extglob
。 - chepner我比较喜欢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"
[[]] 更改为 [] 来转换为经典的Bourne shell。
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
var=" "
,应该被视为空还是非空? - Arkadiusz Drabczyk