2013-12-08 11 views
40

は、誰かがbashのスクリプトで-eq==の違いを説明していただけますか?バッシュ平等演算子(==、-eq)

は、以下の間のいずれかの違いはありますか?

[ $a -eq $b ][ $a == $b ]

それは変数が数字が含まれている場合==にのみ使用されていることを単にですか?

答えて

54

それは周りに他の方法です:==-eqが数値のもののためである、文字列比較のためです。 -eq-lt,-le,-gt,-geおよび-neと同じファミリにありますが、これはどちらが覚えているかを覚えておいてください。

$ [ a == a ]; echo $? 
0 
$ [ a -eq a ]; echo $? 
-bash: [: a: integer expression expected 
2 

==は、bash-ismです。 POSIXフォームは=です。非bashのシェルへの移植性が重要な場合は、=を使用しています。

13

==は、=のbash固有のエイリアスであり、数値比較の代わりに文字列(語彙)比較を実行します。 eqもちろんの数値比較であること。

は最後に、私は通常それはオペレータの周りTest Constructに依存形if [ "$a" == "$b" ]

+6

のみ '=が' POSIXによって指定されるよう== 'ここでは、悪い形である'使い方。 –

+2

あなたが本当に '=='を使うとしたら '[['と ']]'の間に置いてください。 (そして、あなたのスクリプトの最初の行が '/ bin/bash'を使うことを指定していることを確認してください。) – holgero

7

を使用することを好みます。あなたのオプションは、二重括弧、二重の中括弧、単一のブレース、またはtest

あるあなたが((...))を使用する場合は、Cのように==と算術株式をテストしている:

$ ((1==1)); echo $? 
0 
$ ((1==2)); echo $? 
1 

(注意:0は、UNIXでtrueを意味し、二重括弧の内部-eqを使用した感覚と非ゼロ失敗したテストである)

は構文エラーです。

あなたはarithmetic comparisonとして-eq、-ne、-lt、-le、-gtの1、あるいは-geを使用することができますtest[...](またはシングルブレース)または[[...]](またはダブルブレース)を使用して、またはしている場合。

$ [ 1 -eq 1 ]; echo $? 
0 
$ [ 1 -eq 2 ]; echo $? 
1 
$ test 1 -eq 1; echo $? 
0 

==単一または二重括弧(またはtestコマンド)の内部には、string comparison operatorsの一つである:文字列演算子として

$ [[ "abc" == "abc" ]]; echo $? 
0 
$ [[ "abc" == "ABC" ]]; echo $? 
1 

===に相当し、=周りに空白を注意または==が必要です。

となりますが、[[ 1 == 1 ]]または[[ $((1+1)) == 2 ]]は算術的平等ではなく、文字列の等価性をテストしています。

$ [[ $((1+1)) -eq "2 " ]]; echo $? 
0 

同じの文字列比較しながら:だから-eq結果を生成し、おそらく1+1の整数値は、RHが文字列であり、末尾にスペースがあっても2に等しくなることを期待

末尾のスペースをピックアップして文字列の比較に失敗します。

$ [[ $((1+1)) == "2 " ]]; echo $? 
1 

そして、誤った文字列比較で完全なe間違った答え。 '10'は辞書表記で '2'より小さいので、文字列比較はtrueまたは0を返します。だから、多くはこのバグにかまれ:10が2以上算術少ないもののための正しいテスト対

$ [[ 10 < 2 ]]; echo $? 
0 

コメントで
$ [[ 10 -lt 2 ]]; echo $? 
1 

、技術的の質問があります文字列の整数-eqを使用する理由は、同じでない文字列に対してTrueを返します。

$ [[ "yes" -eq "no" ]]; echo $? 
0 

理由は、Bashがuntypedであるためです。 -eqは、文字列を整数として解釈されますベース変換を含む可能場合:

$ [[ "yes" -eq 0 ]]; echo $? 
0 
$ [[ "yes" -eq 1 ]]; echo $? 
1 

ので[[ "yes" -eq "no" ]][[ 0 -eq 0 ]]

と同等です:

$ [[ "0x10" -eq 16 ]]; echo $? 
0 
$ [[ "010" -eq 8 ]]; echo $? 
0 
$ [[ "100" -eq 100 ]]; echo $? 
0 

そして0はbashが、それは単なる文字列であると考えるならば

最後の注意:Test ConstructsのBash固有の拡張の多くはPOSIXではないため、他のシェルでは失敗します。他のシェルは、一般に[[...]]((...))または==をサポートしていません。

+0

'[[" yes "-eq" no "]]'がTrueを返す*技術的な理由が不思議です。 bashはこれらの文字列を比較できる整数値にどのように変換しますか? ;-) – odony

+1

バッシュ変数は[型なし](http://www.tldp.org/LDP/abs/html/untyped.html)ですので、 '[[" yes "-eq" no "]]'は ' [["yes" -eq 0]] 'または[[" yes "-eq" any_noninteger_string "]]' - すべてTrue。 '-eq'は整数比較を強制します。 '' yes ''は整数' 0'と解釈されます。他の整数が「0」であるか、結果が「0」である場合には、比較は真である。 – dawg

+0

@odony:更新を参照 – dawg

0

人:いくつかの回答は危険な例を示しています。 OPの例[ $a == $b ]は特に引用符のない変数置換を使用しました(Oct '17現在の編集)。文字列の等しい場合に安全な[...]の場合

しかし、[[...]]のような代替案を列挙する場合は、右辺を引用符で囲む必要があります。引用符で囲まれていない場合は、パターンマッチです! (bashのmanページから: "パターンの任意の部分を引用符で囲んで文字列として一致させることができます")。

ここではbashで、「はい」もたらす二つの文は、パターンマッチングされ、他の3つは、文字列の平等です:

$ rht="A*" 
$ lft="AB" 
$ [ $lft = $rht ] && echo yes 
$ [ $lft == $rht ] && echo yes 
$ [[ $lft = $rht ]] && echo yes 
yes 
$ [[ $lft == $rht ]] && echo yes 
yes 
$ [[ $lft == "$rht" ]] && echo yes 
$ 
関連する問題