let、expr、$ []の違い


23

私は正確に何が違いますか知りたいです

a=$[1+1]
a=$((1+1))
let a=1+1
a=$(expr 1 + 1 )

4つすべてが変数aに2を割り当てますが、違いは何ですか?

私がこれまでに発見したことから、exprは実際のシェル組み込みではないため、遅いということです。しかし、それ以上のものはありません。

回答:


25

これらはすべて算術を扱いますが、方法は異なり、変数は異なる方法で作成されます。これらのいくつかはbashシェルに固有ですが、他のものはそうではありません。

  • $((...))算術展開と呼ばれ、これはbashkshシェルの典型です。これにより、単純な整数演算が可能になりますが、浮動小数点は使用できません。中のように式の結果は、式を置き換えるecho $((1+1))になりますecho 2
  • ((...))算術評価と呼ばれ、if ((...)); thenor while ((...)) ; doステートメントの一部として使用できます。算術展開展開$((..))は、演算の出力を置き換え、変数を割り当てるために使用できますi=$((i+1))が、条件ステートメントでは使用できません。
  • $[...] 非推奨の算術展開の古い構文です。も参照してください。古いbashスクリプトが壊れないように、これはおそらく維持されました。これはで動作しませんでしたksh93ので、私の推測では、この構文はbash固有のものです。:ここではスペースが非常に重要です。の$[1+1]ようなものと混同しないでください[ $a -eq $b ][スペースでは、として知られているtestコマンド、そしてあなたは、一般的に意思決定の部分でそれを参照してください。動作と目的が大きく異なります。
  • letは、単純な算術評価で変数を作成できるbashand kshキーワードです。そこに文字列を割り当てようとするとlet a="hello world"、構文エラーが発生します。Worksでbashksh93
  • $(...)コマンド置換で、文字通りコマンドの出力を取得して変数に割り当てます。ここでのコマンドはexpr、です。これは、などの位置引数をexpr arg1 arg2 arg3使用するため、スペースが重要です。整数演算用の小さなコマンドライン計算機に加えて、いくつかのtrue / falseおよび正規表現タイプのものに似ています。これはシェルに依存しないコマンドです。

また、算術展開とコマンド置換がで指定されていることは注目に値しますPOSIX標準ながら、let$[...]ではありません。


1
((...))実際に割り当てのために使用することができbashkshそしてzshn=10; ((n+=10)); echo $nプリント20と((x=1)); echo $xプリント1
Alexejマグラ

1
@Alexejありがとう。回答が更新され、その部分は削除されました
Sergiy Kolodyazhnyy

11
  • letコマンドは算術評価を実行し、組み込みのシェルです。

    • このコマンドを実行すると、何も得られません(評価のみ):

      let 1+2
  • $(( ))算術演算を実行するために使用される拡張をここで読みます

    • これを実行すると、エラーが発生します(展開のため):

      $((1+2))
  • $[ ] 算術展開の古い構文です:

    古い形式の$ [expression]は非推奨であり、bashの予定で削除されます。 バッシュマンページ

  • expr はバイナリコマンドです。コマンド置換内で算術展開を行いたい場合は、それを使用できます:

    echo $(expr 1 + 2) 
    echo `expr 1 + 2`

4

上記の回答のいくつかは具体的に言及ksh93しているので、浮動小数点演算ができることに注意する価値があります。たとえば:

$ print $((1.0/3)) 
0.333333333333333333

printfを使用して、出力の精度を制御できます。例:

$ printf "%.4f\n" $((1.0/3))
0.3333

上記のように、少なくとも1つの引数を浮動小数点数として指定する必要があります。両方が整数として指定されている場合、整数演算のみが行われます。例:

$ print $((1/3))  
0

これは、外部コマンドの呼び出しを回避できるため、シェルスクリプトで浮動小数点演算が必要な場合に役立ちます。


bashスクリプトで分数/小数を使用できますか?に回答を投稿することに興味があるかもしれませんタイトルにも関わらず、他のボーンスタイルのシェルが関連していることは文脈から明らかだと思うのでzsh答えを投稿しましkshbashは(一般に)どちらよりも似ているので、その質問への回答は非常に有用zshであると思われますkh93
エリアケイガン

1

letcronでは機能しません。それはlet、独自の環境があるためだと思います。$((...))POSIXなので使用してください。例えば、

let x=1+2
echo x=$x

cronでは、「x =」になりますが、シェルから実行すると「x = 3」になります。

x=$((1+2))
echo x=$x

すべての場合で「x = 3」になります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.