2016-10-18 4 views
1

私はこのようなbashで配列のインデックスで算術展開、使用:Bash:配列インデックスの算術展開 - ドル記号が必要ですか?

declare -a FILES 
declare -i INDEX=0 

for FILE in ./* 
do 
    FILES[((INDEX++))]="$FILE" 
done 

を私は((...))の前にドル記号が必要ですか?

FILES[((INDEX++))]="$FILE" 

いうか::

FILES[$((INDEX++))]="$FILE" 


は、だから、する必要もありませんか?
私のローカルコピーのbashでは両方の亜種が動作するようです - バージョン4.3.30です。
私は、算術式の結果を返すとしか思えないので、後者の方がうまくいくと思います。しかし、そこに:Bash - arithmetic in array index私は最初のバージョンのbash(?)で動作するかもしれないことを読んだ。実際にはどちらが正しいですか?そして、なぜ最初のものが動作していますか?まだ具体的な答えは見つかっていない。

+0

、問題はbash' 'のバージョンとは関係ありませんでした。ユーザーは彼のスクリプトにバグを持っていました(バージョンの問題については、バグがあったときにxが空であることがわかりました)。 – Aserre

+0

@Aserre:もちろんあなたは正しいですが、受け入れられた答えに対する彼のコメントに記載されているように、ユーザは構文エラーを受け取るでしょうが、私は彼が彼のコメントに 'let 'キーワードを使用していることを認識しませんでした。 – erbth

答えて

2

アレイでは、bashは算術として[]の間の式を考慮します。したがって

i=2 ; f[i++]=10 

は完璧です。 f[((i++))]の記述も正しいですが、この場合は(())は算術展開演算子ではなく、ネストされたかっことして認識されます。

((expr))はexprを評価し、それが真であれば成功し、$((expr))はその値として展開されることに注意してください。だからf[$((i++))]も正しいです。

最後に$iが最初に拡張されて以来、f[$i++]は必要なものではありません。たとえば、i=j ; f[$i++]は、f[j++]として展開されます。

備考:奇妙な特徴そのbashが$記号なし演算モードで彼ができるすべてを展開している:あなたがリンクされ、質問に

$ unset i j k f 
$ i=j ; j=k ; k=5 ; f[i++]=10 
$ declare -p i j k f 
declare -- i="6" 
declare -- j="k" 
declare -- k="5" 
declare -a f='([5]="10")' 
1

ドル記号は、いくつかの状況で必要とされるではなく、他の人:

$ bash --version 
GNU bash, version 4.3.42(1)-release (x86_64-redhat-linux-gnu) 
Copyright (C) 2013 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 

$ echo ((1+2)) 
bash: syntax error near unexpected token `(' 

$ echo $((1+2)) 
3 

$ for ((x=0; x<3;++x)); do echo $x; done 
0 
1 
2 

$ for $((x=0; x<3;++x)); do echo $x; done 
bash: `$((x=0; x<3;++x))': not a valid identifier 

、bashのmanページを読んだ後、ドル記号がcompound commandsで必要とされていません。

化合物コマンドはシェルプログラミング構造です。各構成は、予約語または制御演算子で始まり、対応する予約語または演算子で終了します。複合コマンドに関連付けられたリダイレクト(リダイレクトを参照)は、明示的にオーバーライドされない限り、その複合コマンド内のすべてのコマンドに適用されます。

ほとんどの場合、複合コマンドの説明のコマンドのリストは、コマンドの残りの部分と1つ以上の改行で区切られ、セミコロンの代わりに改行が続きます。

Bashは、ループ構成、条件付きコマンド、およびコマンドをグループ化して1つの単位として実行するメカニズムを提供します。

for ((expr1 ; expr2 ; expr3))複合コマンドであり、したがって、ドル記号は、算術評価を可能にするために必要とされません。それは予約bashのキーワードで始まっていないのでecho $((expr))一方

複合コマンドないので、算術評価を可能にするために、ドル記号を必要とします。

+0

それは私が理解していない点です:なぜドル記号はエコーでは必要ですが、配列インデックスには必要ではありません。両方のバリアントが配列インデックスで動作するのはなぜですか?しかし、私は 'for 'の場合を理解することができると思う:それはforキーワードのための特殊な構文であると私は言うだろう。 '純粋な '算術拡張はありませんが、3つの算術式で構成された特別な' for'ループがあります。 – erbth

+0

申し訳ありませんが、まだ理解していません。複合コマンドでドル記号が不要なのはなぜですか?コンパウンドコマンドでドル記号が必要な場合、for(())コマンドにドル記号が必要なのはなぜですか?デフォルトで算術評価を使用しないC-like forコマンド(3つの部分を持つ)がありますか?配列のインデックスはどうですか?彼らはコマンドを複合化しているのでしょうか? – erbth