Bashがエラーをスローする、8行目:$ 1:バインドされていない変数


14

私はgetoptsを使用する方法を学ぼうとしているので、解析された入力でスクリプトを使用できます(getoptsの方が良いと思いますが)。パーティションの使用率を返す簡単なスクリプトを作成しようとしています。問題は、bash関数の1つが、関数$1内の変数として参照しているように思われないことです。参照する理由$1get_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

回答:


29

set -u設定されていない変数を参照すると、説明したとおりに中止されます。引数なしでスクリプトを呼び出しているためget_percent、引数なしで呼び出されているため、$1設定が解除されています。

関数を呼び出す前にこれを確認するか、デフォルトの展開を使用してください(まだ他に設定されていない場合${1-default}は展開defaultされます)。


私はこれを疑ったが、私はそれを回避する方法を考えることができなかった。デフォルトの展開で修正されたようです。どうもありがとうございました!
ティモシープーリアム2018

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 }'
}

また、残りの行を少し調整して、出力する2つの値の間に{space} {tab} {space}が表示されず、{tab}しか表示されないようにしました。2つの非表示スペースが本当に必要な場合は、awkをに変更してくださいprintf "%s \t %s\n", $1, $5


これについて調べなければなりません。私はその変数の型に慣れていません。ありがとう
ティモシープーリアム

@TimothyPulliam私は$@あなたのために簡単な説明を追加しました
roaima
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.