web-dev-qa-db-ja.com

Shell 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行目はif ....を示すものです。

この状態の何が問題になっていますか()に何か問題があると思います。

270
user389955

古典的なテクニック(エスケープメタキャラクター):

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演算子は、 test 、別名[のPOSIX仕様の一部であり、主に下位互換性のためです(たとえば、第7版UNIXではtestの一部であるため)。 POSIXによる '陳腐化'。 Bash( 条件式 を参照)は、-a-oの古典的な意味とPOSIXの意味を、引数を取る独自の代替演算子で横取りしているようです。


少し注意して、より現代的な[[演算子を使うことができますが、(例えば)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ブロックで呼び出される関数にラップする必要があります。

331

Bashでは:

if [[ ( $g == 1 && $c == 123 ) || ( $g == 2 && $c == 456 ) ]]
161

/bin/bashを使用すると、以下が動作します。

if [ "$option" = "Y" ] || [ "$option" = "y" ]; then
    echo "Entered $option"
fi
24
sunitha

文字列変数にスペースがあり、存在を確認する場合は注意してください。正しく引用するようにしてください。

if [ ! "${somepath}" ] || [ ! "${otherstring}" ] || [ ! "${barstring}" ] ; then
7
orkoden
$ g=3
$ c=133
$ ([ "$g$c" = "1123" ] || [ "$g$c" = "2456" ]) && echo "abc" || echo "efg"
efg
$ g=1
$ c=123
$ ([ "$g$c" = "1123" ] || [ "$g$c" = "2456" ]) && echo "abc" || echo "efg"
abc
7
ghostdog74
#!/bin/bash

current_usage=$( df -h | grep 'gfsvg-gfslv' | awk {'print $5'} )
echo $current_usage
critical_usage=6%
warning_usage=3%

if [[ ${current_usage%?} -lt ${warning_usage%?} ]]; then
echo OK current usage is $current_usage
Elif [[ ${current_usage%?} -ge ${warning_usage%?} ]] && [[ ${current_usage%?} -lt ${critical_usage%?} ]]; then
echo Warning $current_usage
else
echo Critical $current_usage
fi
0