Bash 抛出错误,第 8 行:$1:未绑定变量

Bash 抛出错误,第 8 行:$1:未绑定变量

我正在尝试学习如何使用 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

答案1

set -u如果您引用尚未设置的变量,将完全按照您的描述中止。您正在不带参数调用脚本,因此get_percent正在不带参数调用,从而导致$1未设置。

在调用函数之前检查这一点,或者使用默认扩展(如果尚未设置为其他内容,${1:-default}则将扩展为其他内容)。default

答案2

这就是 的效果set -u

您可以检查$#函数内部并避免引用$1(如果未设置)。

您可以通过它$#访问多个参数。在全局上下文中,它是脚本的参数数量,在函数中,它是函数的参数数量。

在问题的上下文中,它是

if [ $# -ge 1 ] && [ -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

请注意,您必须使用[ $# -ge 1 ] && [ -n "$1" ]and not [ $# -ge 1 -a -n "$1" ],因为它会首先评估$1然后检查$#

答案3

其他答案都提到了这是 的效果set -u。其他答案都没有提到set -u可以通过以下方式逆转set +u

$ echo $VAR  # nothing echoed below as VAR is unset:

$ set -u
$ echo $VAR
bash: VAR: unbound variable
$ set +u
$ echo $VAR  # nothing echoed below as VAR is unset:

答案4

因为这是你可以绕过对设置bash的检查,只使用(是第一个参数,是所有参数;当用双引号引起来时,如果它没有值,它会完全消失,这可以避免它被 捕获):$1"$@"$1$@set -u

get_percent() {
    df -h "$@" | awk 'NR>1 { printf "%s\t%s\n", $1, $5 }'
}

我还稍微调整了该行的其余部分,这样您输出的两个值之间就不会出现 {space}{tab}{space} ,但您只会得到一个 {tab} 。如果您确实想要两个不可见的空间,请更改awk为使用printf "%s \t %s\n", $1, $5

相关内容