我正在尝试学习如何使用 getopts,以便我可以拥有带有解析输入的脚本(尽管我认为 getopts 可能会更好)。我正在尝试编写一个简单的脚本来返回分区使用百分比。问题是我的一个 bash 函数似乎不喜欢我$1
在函数中作为变量引用。我引用的原因$1
是因为该get_percent
函数可以传递一个挂载点作为可选参数来显示,而不是所有的挂载点。
剧本
#!/usr/bin/bash
set -e
set -u
set -o pipefail
get_percent(){
if [ -n "$1" ]
then
df -h $1 | tail -n +2 | awk '{ print $1,"\t",$5 }'
else
df -h | tail -n +2 | awk '{ print $1,"\t",$5 }'
fi
}
usage(){
echo "script usage: $(basename $0) [-h] [-p] [-m mount_point]" >&2
}
# If the user doesn't supply any arguments, we run the script as normal
if [ $# -eq 0 ];
then
get_percent
exit 0
fi
# ...
输出
$ bash thing.sh
thing.sh: line 8: $1: unbound variable
$ bash -x thing.sh
+ set -e
+ set -u
+ set -o pipefail
+ '[' 0 -eq 0 ']'
+ get_percent
thing.sh: line 8: $1: unbound variable
set -u
如果您引用尚未设置的变量,将完全按照您的描述中止。您正在调用不带参数的脚本,因此不带参数调用脚本get_percent
,导致未$1
设置。在调用您的函数之前检查这一点,或者使用默认扩展(如果尚未设置为其他内容
${1-default}
,则将扩展为)。default
这是 的效果
set -u
。如果未设置,您可以检查
$#
函数内部并避免引用。$1
与
$#
您可以访问参数的数量。在全局上下文中,它是脚本的参数数量,在函数中,它是函数的参数数量。在问题的上下文中,它是
请注意,您必须使用
[ $# -ge 1 ] && [ -n "$1" ]
而不是[ $# -ge 1 -a -n "$1" ]
,因为这将首先评估$1
然后检查$#
。在脚本中使用“set -u”,对未设置变量的任何引用都会导致错误,尤其是测试它是否具有值,这就是脚本正在执行的操作。
以下函数将在不触发 set -u 的情况下测试未设置的变量:
使用它:
if:IsSet someVariableName || echo "someVariableName is not set"
至于实际函数,测试是否传入了参数,而不是是否为空。这将避免未设置变量的问题,而无需您采取任何特殊步骤,例如测试变量是否具有值。
顺便说一句:函数名中的冒号只是一个字符。它在 Bash 中的函数名中有效,%、}、{、[ 和其他一堆 :-)
由于这是
bash
您可以回避设置的检查$1
而只使用"$@"
($1
是第一个参数,$@
是所有参数;当双引号时,如果它没有值,它会完全消失,从而避免它被 捕获set -u
):我还稍微调整了该行的其余部分,这样您就不会在输出的两个值之间得到 {space}{tab}{space},但实际上您只会得到一个 {tab}。如果你真的想要两个不可见的空间,那么
awk
将printf "%s \t %s\n", $1, $5
.其他答案已经提到这是 的效果
set -u
。其他答案都没有提到set -u
可以通过以下方式逆转set +u
: