このコマンドがある場合:
expr 2 * 4
*
ワイルドカードが評価されるため、エスケープする必要があるため機能しません。
expr 2 \* 4
ただし、次の2つの状況が発生した場合:
let var1=2*4
var2=$((2*4))
これにより、*
ワイルドカードは評価されず、エスケープする必要はありません。
*
上記の2つのケースでワイルドカードが評価されないのはなぜですか?私の考えでは、bash
andを使用したときにまったく評価されていないようです。let
$(())
この場合、ワイルドカードが評価されない他の状況はありますか?
答え1
では、var2=2*4
空白(メタ文字)のため、2
a、一部の文字、および4で始まるファイルはpwdには存在しません。
行は、スペースを区切り文字として使用してトークンに分割されます。
スペースはありません(以降は=
引用されていると見なされます)。
$ var1=2*4
しかしそれははい:
$ echo 2 * 4
タグになって*
拡張されます(ファイル名拡張子として)。
特殊効果に引用符を使用したくない場合は、次のようにします*
。
$ expr 2 \* 4
8
$ expr 2 "*" 4
8
$ expr 2 '*' 4
8
ただし、これは次のように拡張されます。
$ touch 2good4
$ echo 2*4
2good4
では、echo $((2*4))
構文内の内容が$((…))
算術拡張として解釈されます。どちらも同じことを行います(空白があっても)。
$ echo $((2*4))
8
$ echo $(( 2 * 4 ))
8
$ echo $(( 2 * 4 ))
8
答え2
あなたが見ている行動が説明されましたここでワイルドカードそしてこれは拡張用です。そして、man let
Bashのパラメータ仕様ページは「let」を提供することを知っています。
Bashが自分自身を見ると、*
パス名拡張を行います。とは別に
拡張がnull結果を返す場合、この場合はリテラル文字列を返します。
echo 2 * 4 #echo 2, the contents of the pwd and then 4
*
微分形式または拡張(数学/コマンド/パラメータまたはまったく拡張なし)を使用するように指示するフラグが前にある場合は、関連する方法を使用します。だから
let var1=2*4 #pass the **arithmetic** argument var1=2*4 to the let command because bash knows let takes special characters (% * etc) as arguments
var2=$((2*4)) #bash parses the string as far as $ and sees an instruction to expand
#bash then sees (( the which specifies arithmetic expansion specifies
あなたが言ったように
echo 2 \* 4 #perform no expansion
答え3
理由を知りたい場合は、bashができることとbashがコマンドを解析する方法を知る必要があります。
まず、*がbashでできることは次のとおりです。
ファイル名globのワイルドカード
取る
正規表現で0回以上発生
...
そしてbashがコマンドを解析する方法(非常にシンプルで実際には非常に複雑です):
パラメータの置換
コマンドの置き換え
ワイルドカード
...
あなたが持っていると仮定a.txt b.txt現在のディレクトリでexpr 2 * 4
パラメータ置換->コマンド置換->ワイルドカードを適用すると、次のようになります。
expr 2 a.txt b.txt 4
正解を返さないのはなぜですか?
しかし、ではexpr 2 \* 4
*が文字です!パラメータ置換、コマンド置換、ワイルドカードは影響しません。したがって、exprは3つのパラメータ2 * 4を取得し、8を返します。
Bashでは、let var1=2*4
globbingの前に算術置換が行われ、globbingの後のコマンドはですlet var1=8
。現在のディレクトリに2a4 2b4があり、letを使用していない場合は、
var1=2*4
echo $var1
8以外の2a4 2b4を返します。
では、var2=$((2*4))
bashは(())が算術演算子であるため、算術置換も実行します。
添付:* を算術演算子として使用するには、(())$[] 内に保持するか、let を使用します。たとえば、次のようになります。
((var1 = 2 * 4)) or var1=$((2 * 4))
var1=$[2 * 4]
空白が許可されます!