Bash引发错误,第8行:$ 1:未绑定变量


15

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

我认为这与无关getopts,不是吗?您的脚本因-u调用之前退出getopts
ilkkachu

@ikkachu不,我猜不是。但是我不确定现在是否可以更改标题。
蒂莫西·皮里亚姆

帖子下应该有一个小的“编辑”文本,位于问题中标签的下面
ilkkachu

Answers:


29

set -u如果引用了一个未设置的变量,它将完全按照您的描述中止。您在不带参数的情况下调用脚本,因此get_percent在不带参数的情况下被调用,导致未$1设置。

可以在调用函数之前进行检查,或者使用默认扩展名(如果尚未设置为其他${1-default}扩展名,则将扩展为default)。


我对此表示怀疑,但我想不出解决办法。默认扩展似乎已修复它。非常感谢你!
蒂莫西·皮里亚姆

7
特别是,可以使用[ -n "${1-}" ](即默认值为空)来查看该参数是否已设置且为非空。或[ "${1+x}" = x ]查看是否已设置(即使为空)。
ilkkachu

尽管使用了if [[ -n ${1-default} ]]
Chaitanya Bapat,

6

这是的效果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" ]而不是[ $# -ge 1 -a -n "$1" ],因为那样会先评估$1然后再检查$#


您能否解释更多如何使用$#以及如何检查它?谢谢
Chaitanya Bapat

1
我加了一个例子。
RalfFriedl

3

既然这样,bash您就可以避开设置检查$1并仅使用它"$@"$1是第一个参数,$@是所有这些;用双引号括起来的话,如果没有值,它将完全消失,从而避免被捕获set -u):

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

我还对行的其余部分进行了微调,以使您不会在输出的两个值之间得到{space} {tab} {space},而在输入中只能得到{tab}。如果您确实想要两个不可见的空格,请更改awkprintf "%s \t %s\n", $1, $5


我将不得不对此进行调查。我不熟悉该变量类型。谢谢
Timothy Pulliam '18

@TimothyPulliam我$@为您添加了简短说明
roaima
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.