複数の条件を次のように表現したいと思います。
if [ ( $g -eq 1 -a "$c" = "123" ) -o ( $g -eq 2 -a "$c" = "456" ) ]
then
echo abc;
else
echo efg;
fi
しかし、スクリプトを実行すると、
syntax error at line 15: `[' unexpected,
15 行目は、... を示しています。
この症状の何が問題なのでしょうか? に何か問題があるのではないかと思います()
。
ベストアンサー1
古典的な手法(メタ文字をエスケープする):
if [ \( "$g" -eq 1 -a "$c" = "123" \) -o \( "$g" -eq 2 -a "$c" = "456" \) ]
then echo abc
else echo efg
fi
への参照を二重引用符で囲みましたが、これは一般的に良い方法です。厳密に言えば、との優先順位により括弧がなくても正しい$g
ため、括弧は必要ありません。-a
-o
-a
および-o
演算子はPOSIX仕様の一部であることに注意してください。test
、別名 は、主に下位互換性のために存在します(たとえば、7th Edition UNIXでは の[
一部であったため)が、POSIXでは明示的に「廃止予定」とマークされています。Bash(test
条件式) は、引数を取る独自の代替演算子を使用して、およびの-a
従来の POSIX の意味を優先しているようです。-o
少し注意すれば、より新しい[[
演算子を使用することもできますが、Bash と Korn Shell (たとえば) のバージョンは同一である必要はないことに注意してください。
for g in 1 2 3
do
for c in 123 456 789
do
if [[ ( "$g" -eq 1 && "$c" = "123" ) || ( "$g" -eq 2 && "$c" = "456" ) ]]
then echo "g = $g; c = $c; true"
else echo "g = $g; c = $c; false"
fi
done
done
Mac OS X 上の Bash 3.2.57 を使用した実行例:
g = 1; c = 123; true
g = 1; c = 456; false
g = 1; c = 789; false
g = 2; c = 123; false
g = 2; c = 456; true
g = 2; c = 789; false
g = 3; c = 123; false
g = 3; c = 456; false
g = 3; c = 789; false
の場合と同じように、これは別のコマンドではないため、 の場合[[
のように変数を引用符で囲む必要はありません。[
[
それは古典的な質問ではないでしょうか?
そう思うでしょう。しかし、別の選択肢もあります。
if [ "$g" -eq 1 -a "$c" = "123" ] || [ "$g" -eq 2 -a "$c" = "456" ]
then echo abc
else echo efg
fi
実際、ツールや関連パッケージの「ポータブル シェル」ガイドラインを読むとautoconf
、この表記法 (「||
」と「&&
」を使用) が推奨されています。次のようにもできると思います。
if [ "$g" -eq 1 ] && [ "$c" = "123" ]
then echo abc
elif [ "$g" -eq 2 ] && [ "$c" = "456" ]
then echo abc
else echo efg
fi
アクションがエコーのように単純な場合は、これは悪くありません。繰り返すアクション ブロックが複数行にわたる場合、繰り返しが面倒すぎるため、以前のバージョンのいずれかが望ましいです。または、アクションを、異なるブロックで呼び出される関数にラップする必要がありますthen
。