シェルのif文で複数の条件を表現するにはどうすればいいですか? 質問する

シェルのif文で複数の条件を表現するにはどうすればいいですか? 質問する

複数の条件を次のように表現したいと思います。

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

おすすめ記事