web-dev-qa-db-ja.com

bashスクリプトで「単項演算子が必要」に遭遇

私のbashスクリプトには、後のメイン関数の条件に対して0または1(trueまたはfalse)を返す関数があります。

function1 () { 
    if [[ "${1}" =~ "^ ...some regexp... $" ]] ; then
        return 1
    else
        return 0
    fi 
}

次に、私の主な機能で:

main () { 
    for arg in ${@} ; do
        if [ function1 ${arg} ] ; then
            ...
        Elif [ ... ] ; then
            ...
        fi
    done
}

ただし、このスクリプトを実行すると、常にエラーメッセージ「[:function1:単項演算子が必要です」が表示されました。

誰か助けてくれませんか?

12
GJ.

[ifコマンドの構文の一部であると想定するというよくある間違いを犯しています。そうではない; ifの構文は単純です

if command; then
    ... things which should happen if command's result code was 0
else
    ... things which should happen otherwise
fi

私たちが使用する一般的なcommandsの1つは、コマンドtestのエイリアスである[です。文字列、数値、ファイルを比較するための簡単なコマンドです。かなり狭い引数の組み合わせを受け入れ、期待される引数を渡さないと、紛らわしく誤解を招くエラーメッセージが生成される傾向があります。 (むしろ、エラーメッセージは、慣れれば適切で役立ちますが、慣れていない場合は簡単に誤解されます。)

main関数で、[の呼び出しが誤って配置されているように見えます。あなたはおそらく意味します

if function "$arg"; then
    ...
Elif ... ; then ...

ちなみに、適切な方法として、常に文字列を引用する必要があります。 "$1"ではなく$1を使用し、"$arg"ではなく$argを使用します。

著者がtestの構文の一部にしたくなかったものの一般的な台所の流し台としてのifの歴史的な理由は、元のBourneShellのあまり魅力的でないデザインの1つです。 Bashとzshは、扱いにくい代替手段を提供します([[定義で使用するbashのfunction1二重括弧など)。もちろん、POSIX testは、ベル研究所のオリジナルの作品よりもはるかに優れています。

追加の説明として、関数を単純化して次のようにすることができます。

function1 () {
    ! [[ "$1" =~ "^ ...some regexp... $" ]]
}

つまり、[[を使用してテストを実行し、その結果コードを逆にします。 (「通常の」ケースでは、成功した場合は0を返しますが、文字列が一致しないことを確認しようとしている可能性がありますか?)

29
tripleee