変数を文字列または整数で比較する際に重要な違いはありますか?

変数を文字列または整数で比較する際に重要な違いはありますか?

不思議なことに、bash変数の比較(値はan)を実行するときに、integeranまたはaと宣言された事前定義さintれた値についてテストできますstring

サンプルスクリプト:

#!/bin/bash
f1()
{
        [ "$1" == "1" ] && echo "$FUNCNAME: \"1\" compared as string"
}

f2()
{
        [[ "$1" -eq 1 ]] && echo "$FUNCNAME: \"1\" compared as int"
}

f1 $1
f2 $1

出力:

$  ./param.sh 1
f1: "1" compared as string
f2: "1" compared as int

そして

$  ./param.sh blah
$

どちらの関数も同じように動作するので、整数変数をチェックするときに好む方法があるかどうか疑問に思います。もっと厳しいので、intvsを確認したいのですが、これintは欠点があるかどうか疑問に思いますstring

この場合、f2()比較もさらに厳しくなる。つまり、10進値を渡すと値が壊れますが、渡すとf1()問題はありません。

答え1

はい、多くの違いがあります。たとえば、=文字列がまったく同じであることを確認し、-eq同じであることを確認する前に、両方の式に対して算術を実行します。

$ [ " 1 " -eq 1 ] && echo equal || echo not
equal
$ [ " 1 " = 1 ] && echo equal || echo not
not

$ [ +1 -eq 1 ] && echo equal || echo not
equal
$ [ +1 = 1 ] && echo equal || echo not
not

$ [ "0+1" -eq 1 ] && echo equal || echo not
equal
$ [ "0+1" = 1 ] && echo equal || echo not
not

さらに、空の文字列は数値で正確にゼロに等しくなります。

$ [ "" -eq 0 ] && echo equal || echo not
equal
$ [ "" = 0 ] && echo equal || echo not
not

比較演算子を導入すると、別の種類の違いが発生します。たとえば、<vsを考えてみましょう。-lt

$ [[ 2 -lt 10 ]] && echo less || echo not
less
$ [[ 2 < 10 ]] && echo less || echo not
not

これは、文字列「2」が文字列「10」の後にアルファベット順に続くが(1が2よりも前にあるため)、数字「2」が数字「10」より数値的に小さいためです。

答え2

整数と文字列の比較は、以下より大きいか小さい場合に最も重要です。

#!/bin/bash

eleven=11
nine=9

[[ $nine < $eleven ]] && echo string   # fail

[[ "$nine" -lt "$eleven" ]] && echo integer # pass

辞書式で並べ替えると、9が11の後に来るため、最初は失敗します。

引用符を使用して文字列を比較するか数値を比較するかを決定するのではなく、演算子が決定します。上記の引用符を追加または削除できますが、違いはありません。 Bash は二重括弧内に定義されていない変数をキャプチャするため、引用符は必要ありません。数値テストに小括弧で引用符を使用すると、次の理由でコストが節約されません。

[ "" -lt 11 ]

とにかくエラーです(「整数式が必要です」)。引用符は、単一の括弧内の文字列比較に対する効果的な保護です。

[ "" \< 11 ]

コメント内ダブル括弧内は""will-eq 0ですがwill notです== 0

答え3

言ったことに加えて。
シェルスクリプトでは速い計算はほとんど必要ありませんが、数値が等しいかどうかを比較する方が高速です。

$ b=234
$ time for ((a=1;a<1000000;a++)); do [[ $b = "234" ]]; done

real    0m13.008s
user    0m12.677s
sys 0m0.312s

$ time for ((a=1;a<1000000;a++)); do [[ $b -eq 234 ]]; done

real    0m10.266s
user    0m9.657s
sys 0m0.572s

関連情報