if [](角括弧)からの「[:多すぎる引数」エラーの意味


211

次のBASHシェルエラーの意味を説明し、修正する単純な簡単なリソースが見つからなかったため、調査した結果を投稿します。

エラー:

-bash: [: too many arguments

Googleと相性の良いバージョン: bash open square bracket colon too many arguments

コンテキスト:等しい、より大きいなどの単純な比較演算子を使用した、単一の角括弧内のif条件。次に例を示します。

VARIABLE=$(/some/command);
if [ $VARIABLE == 0 ]; then
  # some action
fi 

1
この特定のエラーを生成したコードはどこにありますか?
アンダーソングリーン

回答:


353

あなたの場合は$VARIABLEスペースやその他の特殊文字、文字列ですと、単一の角括弧を使用している(のショートカットであるtestコマンド)、その文字列を複数の単語に出て分割することができます。これらはそれぞれ個別の引数として扱われます。

したがって、1つの変数が多くの引数に分割されます

VARIABLE=$(/some/command);  
# returns "hello world"

if [ $VARIABLE == 0 ]; then
  # fails as if you wrote:
  # if [ hello world == 0 ]
fi 

スペースやその他の特殊文字を含む文字列を置く関数呼び出しについても同じことが言えます。


簡単な修正

変数の出力を二重引用符で囲み、強制的に1つの文字列(したがって1つの引数)のままにします。例えば、

VARIABLE=$(/some/command);
if [ "$VARIABLE" == 0 ]; then
  # some action
fi 

そのような単純な。ただし、変数が空の文字列または空白のみを含む文字列でないことも保証できない場合は、以下の「注意してください...」に進んでください。


または、代わりの修正は、二重の角括弧(new testコマンドのショートカット)を使用することです。

これはbash(そして明らかにkornとzsh)にのみ存在するため、/bin/shetc によって呼び出されるデフォルトのシェルと互換性がない場合があります。

これは、一部のシステムでは、すべての構成方法によっては、コンソールからは機能するが、のように他の場所から呼び出されたときに機能しない場合があることをcron意味します。

次のようになります。

VARIABLE=$(/some/command);
if [[ $VARIABLE == 0 ]]; then
  # some action
fi 

コマンドにこのような二重角かっこが含まれていて、ログでエラーが発生したがコンソールからは機能[[する場合は、ここで提案されている代替案をに交換するか、スクリプトの実行内容が[[aka をサポートするシェルを使用していることを確認してくださいnew test


[: unary operator expectedエラーにも注意してください

「引数が多すぎます」というエラーが表示された場合は、予測できない出力の関数から文字列を取得している可能性があります。空の文字列(またはすべての空白文字列)を取得することも可能な場合、これは上記の「クイックフィックス」を使用しても引数なしとして扱われ、失敗します。[: unary operator expected

他の言語に慣れている場合も同じです。変数が評価される前に、変数の内容がこのようなコードに効果的に出力されるとは期待していません。

[: too many arguments[: unary operator expectedエラーの両方を防ぐ例を次に示します。出力が空の場合(この例では0)、デフォルト値で置き換え、全体を二重引用符で囲みます。

VARIABLE=$(/some/command);
if [ "${VARIABLE:-0}" == 0 ]; then
  # some action
fi 

(ここでは、$ VARIABLEが0または空の場合にアクションが発生します。当然、異なる動作が必要な場合は、0(デフォルト値)を別のデフォルト値に変更する必要があります)


最後の注記:[はのショートカットなのでtest、上記のすべてはエラーにも当てはまりますtest: too many arguments(またtest: unary operator expected


さらに良い方法はi=$(some_command); i=$((i)); if [ "$i" == 0 ] ...
Jo So

1
ターミナルを介して実行するとBASHをインタープリターとして使用するShellscriptは問題なく動作する問題を経験しましたが、Crontabを介して実行すると、このようなエラーが発生し、Postfixを介してローカルEメールを送信して、このエラーを通知しました。特殊文字が含まれる変数のIF。二重引用符は私の命を救った。ありがとうございました :)!
ivanleoncz

13

同じエラーが発生し、この投稿にぶつかっただけで、2つの変数が両方とも空(または空ではない)かどうかをテストしようとしました。それは複合比較であることがわかります-7.3。その他の比較演算子-Advanced Bash-Scripting Guide ; そして私は次のことに注意すべきだと思いました:

  • 私が使用し-e、それは最初に「空」の意味を考えて。しかし、それは「ファイルが存在する」という意味です- -z空の変数(文字列)のテストに使用します
  • 文字列変数は引用符で囲む必要があります
  • 複合論理AND比較の場合、次のいずれかです。
    • 2つtestのと&&それらを使用します。[ ... ] && [ ... ]
    • または-a、単一の演算子を使用しますtest[ ... -a ... ]

これが動作するコマンドです(ディレクトリ内のすべてのtxtファイルを検索しgrep、2つの単語の両方が含まれていることが見つかったファイルをダンプします)。

find /usr/share/doc -name '*.txt' | while read file; do \
  a1=$(grep -H "description" $file); \
  a2=$(grep -H "changes" $file); \
  [ ! -z "$a1" -a ! -z "$a2"  ] && echo -e "$a1 \n $a2" ; \
done

2013年8月12日を編集:関連する問題のメモ:

古典の文字列の等価性チェックするときことに注意してくださいtest(単一の正方形ブラケット[)、あなたがしなければならない。この場合には、単一である「ある等しい」演算子は、「等しい」の間にスペースを持つ=2つのイコールの兆候があるが、符号を(==平等として受け入れているように見えます演算子も)。したがって、これは(サイレントに)失敗します:

$ if [ "1"=="" ] ; then echo A; else echo B; fi 
A
$ if [ "1"="" ] ; then echo A; else echo B; fi 
A
$ if [ "1"="" ] && [ "1"="1" ] ; then echo A; else echo B; fi 
A
$ if [ "1"=="" ] && [ "1"=="1" ] ; then echo A; else echo B; fi 
A

...しかしスペースを追加します-そしてすべてが美しく見えます:

$ if [ "1" = "" ] ; then echo A; else echo B; fi 
B
$ if [ "1" == "" ] ; then echo A; else echo B; fi 
B
$ if [ "1" = "" -a "1" = "1" ] ; then echo A; else echo B; fi 
B
$ if [ "1" == "" -a "1" == "1" ] ; then echo A; else echo B; fi 
B

bashシェルの例を提供できます((A || B) && C)か?
jww

質問3826425および14964805
splaisan

たとえば、ループがある場合などに必要な、角かっこ内にコマンドを完全に含める方法を示していないため、これは実際にはそれほど役に立ちません。
ティモシースワン

5

[: too many argumentsまたは[: a: binary operator expectedエラーが発生する別のシナリオは、すべての引数をテストしようとした場合です"$@"

if [ -z "$@" ]
then
    echo "Argument required."
fi

foo.shまたはを呼び出すと、正しく機能しますfoo.sh arg1。ただし、のようfoo.sh arg1 arg2に複数の引数を渡すと、エラーが発生します。これは[ -z arg1 arg2 ]、有効な構文ではないに展開されているためです。

引数の存在を確認する正しい方法は[ "$#" -eq 0 ]です。($#は引数の数です)。


2

誤ってキーボードに触れてスペースを削除した場合。

if [ "$myvar" = "something"]; then
    do something
fi

このエラーメッセージが表示されます。']'の前のスペースが必要であることに注意してください。


1
その結果、次のような別の構文エラーが発生すると思います。21行目:[:行方不明の `] '
Joe Holloway

1

私のスクリプトにも同じ問題がありました。しかし、私がいくつかの修正を行ったとき、それは私のために働きました。私はこれを好きでした:-

export k=$(date "+%k");
if [ $k -ge 16 ] 
    then exit 0; 
else 
    echo "good job for nothing"; 
fi;

そのようにして問題を解決しました。それもあなたのために役立つことを願っています。

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