if [ -n $diffCurr ] エラー: パラメータが多すぎます。

if [ -n $diffCurr ] エラー: パラメータが多すぎます。

しばらく以下のコードを使用してきましたが、今はエラーが発生しています。

java Editor < "input/editor$i.in" > "tmp/editor$i.out"
diffCurr="$(diff "tmp/editor$i.out" "output/editor$i.out")"
if [ -n $diffCurr ]

エラー(上記のコードスニペットの最後の行で発生):

[: 引数が多すぎます。

何が問題なの? diff 結果が空であるか(つまり、ファイルの内容が同じか)テストしようとします。

答え1

diffの終了状態によってファイルが異なるかどうかがわかるので、 の出力を変数に入れる必要はありませんdiff

if diff -q file1 file2 >/dev/null 2>&1; then
        # files are equal
else
        # files differ, or an error occurred
fi

diff0ファイルに違いがない場合、成功()が返されます。必要に応じてロジックを調整します。

可能であれば、コマンドの終了状態をテストすることは、コマンド置換を介して出力を検査または解析するよりも、常に常に望ましいです。

"$diffCurr"完全性を期すために、元の例はその行に引用符がないため失敗しますif。したがって、「単語の分離」を複数の単語に進めるので、「引数が多すぎます」。

答え2

jw013 そうなんですね。とにかく、この行は必要ありません。

しかし、実際の質問に答えるために渡した変数test(とも呼ばれる[)の周りの引用符を省略しました。

つまり、変数が空の場合はパラメータがないように(たとえば[ -n ])、変数に空白がある場合は複数のパラメータを渡したようになります(そうなったようです)。

文字列は常にtest引用符で囲みます。たとえば、次のようになります。

if [ -n "$myvar" ]

答え3

diffテスト出力よりもコマンドの終了コードをテストする方が良いでしょう。

diffCurr="$(diff "tmp/editor$i.out" "output/editor$i.out")"
if [ $? -ne 0 ]; then  # different
...

出力に興味がない場合は、jw013の提案に従うことができます。

答え4

上記の良い答えに加えて、bashとの愛/憎しみの関係はパラメータ置換の強みを中心にしており、必要に応じて置換を中止するのは非常に難しいかもしれません。 1回以上。

したがって、私はほとんど常に次の変数参照をエンコードします。

A="${B}"

これにより、B単一の文字列(最も一般的に私が望むもの)として扱われ、次のことが可能になります。

A="${B}foo"

そして、中かっこ内でのみ動作する他の素晴らしいオプションもあります。

単純な安全変数参照を次のようにエンコードすると、

A="${B}"

まず、後で戻ってコードを修正するときに引用符や中括弧がない場合は、失敗する可能性のある操作を実行する方がはるかに安全です。

関連情報