Bash 严格模式定义如下:
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
http://redsymbol.net/articles/unofficial-bash-strict-mode/
考虑以下 Bash 脚本中位置参数的解析:
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
usage() {
echo ""
echo "usage:"
echo "$0 [options]"
echo " -r | --redirect-uri: redirect uri"
echo " -a | --app-role: app role id"
echo " -h | --help: help"
echo ""
}
redirect_uri=""
app_role=""
while [ "$1" != "" ]; do
case $1 in
-r | --redirect-uri)
shift
redirect_uri="$1"
;;
-a | --app-role)
shift
app_role="$1"
;;
-h | --help)
usage
exit 0
;;
*)
usage
exit 1
;;
esac
shift
done
...
这不适用于以下错误,例如:
$ ./app.sh -r https://example.net:8080/auth/callback -a 53b37b21-2c6e-4731-a5e5-15b98052c686
./app.sh: line 18: $1: unbound variable
我认为原因是条件的最终检查while
, after shift
, where$1
是未定义的。
使用 Bash 严格模式时,如何在while
不导致脚本崩溃的情况下终止语句中的参数解析?
您收到
unbound variable
错误是因为您在未定义时尝试访问$1
它,而在循环的最后一次迭代之后它不会出现while
。因此,有问题的命令是您使用的测试while
:相反,使用类似
或者
参数扩展
${parameter+word}
将扩展为word
如果parameter
是一个现有变量(无论它是否具有非空值)。这个词set
是任意选择的,但在某种程度上暗示了它的用途。您还可以测试
$#
,它包含位置参数的数量:或者
只要有位置参数仍需要处理并从列表中移出,这些算术测试都是正确的。
nounset
这些变体中的任何一个都避免了与shell 选项 ( )强加的限制相冲突set -u
。