質問: 下記で、zshでコマンドを確認する時に`(( ${+commands[peco]} ))`のような記述を見かけました。`commands`はzshが自動で用意している実行できるコマンドを含む連想配列だと思っています。 この時、`(( ))`を使うメリットはあるのでしょうか?二重丸括弧は`(( i++ ))`のような計算をする時に使うものだと思っていました。`(( $ ))`のようにドルを中で使うとプロセス番号を取得できますが、上記の場合はプロセス番号ではなく、変数展開`${+val}`のドル記号でした。これは変数が存在するなら1、ない場合は0と評価するものです。 二重丸括弧を使わなくても、`echo ${+commands[bash]}`で`1`と表示させることが出来ました。何か`zsh`では二重丸括弧を使っておかないと困るようなことがあるのでしょうか? どうぞよろしくお願い致します。 * zshでfpathからwhichのように検索する話など - @znz blog * dotfiles/10_utils.zsh at master · b4b4r07/dotfiles
回答: ここで,`(( ))` を利用している理由としては,コマンドが存在するかどうかを調べたいだけであり,`$+commands[zsh]` の返却値である数字でコマンドを実行したくないからだと思います. あと,`${+commands[$1]}` は コマンドが存在すると1存在しないと0を返却します.ただしシェルはコマンドの実行に成功した時0, 失敗した時,0以外が帰ってき, true false が逆になってしまっています. (( )) で囲うことで, 1 の時 0 が帰ってき, 0 のとき 1 が帰ってきて not 的なことができます. なぜ,not的な振る舞いが行われるかというと, (( )) 内で右辺を返却した時,内部的に比較が行われます. 冗長的に書くと,`(( ${+commands[$1]} ))` は `(( ${+commands[$1]} == 1 ))` と同じだからです. 比較に成功すると,コマンドの実行に成功した扱いになり, 1 == 1 で 0 が帰ってきます. zsh の true と false の扱いと, コマンドの実行成功と失敗の扱いで 0 と 1 が全く逆の意味を指しているのがややこしくなっている原因でしょう. :?too few argument そしてこれはおそらく可読性を上げるためのコメント文のようなものだと推測します. : 以下のコマンドは実行されないので. C言語の ``` while ( 1 ) { } ``` とかと同じ感じでしょう. 二重括弧とコロンコマンドについては,http://rcmdnk.github.io/blog/2013/11/13/computer-bash-colon/ などがわかりやすいのではないのでしょうか.