変数を逆参照するときは、記号を使用する必要がbash
あります$
。それにもかかわらず、次はうまくいくようです。
x=5
[[ x -gt 2 ]]
誰でもこれを説明できますか?
編集:(追加情報)
私の言葉は、[[]]コマンドが$記号なしで私の変数xを逆参照する方法と理由を意味します。はい、x = 1の場合、ステートメントはfalseと評価されます(状態1を返します)。
答え1
その理由は、-eq
パラメータの算術的評価を強制するためです。
算術演算子:-eq
、、、-gt
および内部的に(ksh、zsh、およびbashで)変数名はCのように自動的に拡張され、先行が必要ないことを-lt
意味します。-ge
-le
-ne
[[ ]]
$
これを確認するには、bashソースコードを見てください。マニュアルには付属していません直接確認してください。
算術演算子の処理は
test.c
内部的にこの関数に属します。arithcomp (s, t, op, flags)
ここで、と
s
はt
すべてオペランドです。オペランドは関数に渡されます。l = evalexp (s, &expok); r = evalexp (t, &expok);
この関数は、次のヘッダーを使用して
evalexp
内部で定義されます。expr.c
/* expr.c -- arithmetic expression evaluation. */
はい。算術演算子の両方が(直接的に)算術式の評価に属します。直接的で、しかし、ifはありません。
実際、:
$ x=3
どちらも失敗します。
$ [[ x = 4 ]] && echo yes || echo no
no
$ [[ x = 3 ]] && echo yes || echo no
no
これは正確でx
拡張されておらず、x
数字と同じではありません。
しかし:
$ [[ x -eq 3 ]] && echo yes || echo no
yes
$ [[ x -eq 4 ]] && echo yes || echo no
no
名前付き変数はx
拡張されます($なしでも)。
これはzshやbashでは発生しません[…]
(kshでは発生します)。
これは内部で発生するのと同じことです$((…))
。
$ echo $(( x + 7 ))
10
そしてこれは(非常に)再帰的であることを理解してください(ダッシュとヤッシュを除く)。
$ a=b b=c c=d d=e e=f f=3
$ echo "$(( a + 7 ))"
10
ㅏ
答え2
数値比較のオペランド、、、、-eq
およびは算術式で処理され-gt
ます-lt
。-ge
一部の制限により、まだ単一のシェルワードでなければなりません。-le
-ne
算術式における変数名の動作については後述する。シェル算術:
シェル変数はオペランドとして受け入れられます。パラメータ拡張は式の評価前に行われます。式内では、シェル変数はパラメーター拡張構文を使用せずに名前で参照することもできます。nullまたは設定されていないシェル変数は、パラメータ拡張構文を使用せずに名前で参照すると0に評価されます。
そして:
変数の値は、参照時に算術式として評価されます。
しかし、実際には数値の比較には算術式が必要であるという文書の一部を見つけることができません。説明なし条件付き構造以下[[
に説明されていません。Bash条件式。
しかし、実験を通して上記のように動作するようです。
したがって、次のようなものが有効です。
a=6
[[ a -eq 6 ]] && echo y
[[ 1+2+3 -eq 6 ]] && echo y
[[ "1 + 2 + 3" -eq 6 ]] && echo y
これはまた(変数の値を評価することです):
b='1 + 2 + 3'
[[ b -eq 6 ]] && echo y
しかしそうではありません。構文解析時に単一のシェル語ではない[[ .. ]]
ため、条件に構文エラーがあります。
[[ 1 + 2 + 3 -eq 6 ]] && echo y
他の算術コンテキストでは、式に空白があってはなりません。これは999
、括弧がインデックスの算術式を明確に区別するために印刷されます。
a[6]=999; echo ${a[1 + 2 + 3]}
一方、=
比較はパターンマッチング、算術コンテキストで実行される算術または自動変数拡張(条件付き構成)を含みません。
==
and演算子を使用すると、!=
演算子の右側の文字列はパターンとして扱われ、extglobシェルオプションが有効になっているかのように、パターンの一致で説明されている規則に従って一致します。演算子は=
と同じです==
。
文字列が明らかに異なるため、これは間違っています。
[[ "1 + 2 + 3" = 6 ]]
これは値が同じでも同じです。
[[ 6 = 06 ]]
ここで文字列(x
および6
)も比較され、互いに異なります。
x=6
[[ x = 6 ]]
しかし、これは変数を拡張するので、これは本当です。
x=6
[[ $x = 6 ]]
答え3
はい、あなたの観察は正しいです。二重括弧の下の式で変数拡張が実行されるため、変数名の前に[[ ]]
入れる必要はありません。$
これはマニュアルに明確に記載されていますbash
。
[[表現する]]
(...)[[と]]の間の単語については、単語の区切りとパス名の拡張は行われません。チルダ拡張、パラメータおよび変数拡張、算術拡張、コマンド置換、プロセス置換、および引用符の削除が実行されます。
これは、単一の角かっこバージョンの場合には該当しません[ ]
。[
これは、シェルキーワード(構文)ではなく、コマンド(bashには組み込まれており、他のシェルではテストに外部、インラインを使用できる)です。