Bashでの数の取り扱いについて で出てきたコロンコマンドや二重括弧等について 適当に試して分かったりしたことやよく分かってないこと。
コロンコマンド
:
より先に書かれたものは通常無視されますが、
サブシェルを呼ぶ様なコマンドはそのコマンドが実行される様です。
$ : ps > ps.log
$ cat ps.log
では何も出ませんが(ps.logには:
の実行結果、つまり空白が出力される)、
$ : $(ps > ps.log)
$ cat ps.log
PID TTY TIME CMD
16406 pts/197 00:00:00 bash
27787 pts/197 00:00:00 bash
27788 pts/197 00:00:00 ps
と言った感じ。
$ : sleep 10
$ : $(sleep 10)
でも違いがわかると思います。
正しくないコマンドを与えると
$ : invali
$ echo $?
0
$ : $(invalid)
-bash: invalid: command not found
$ echo $?
0
と、通常ただ書いた場合では単に無視され、サブシェルで呼んだ場合には そのエラーは出力されますが(標準出力はそのままでは表示されない) コマンド自体の返り値は0で正常終了しています。
ただ、直接サブシェルだけを立ち上げようと
$ (ls)
の様な感じ(これだと単にlsをサブシェルで実行するだけ)で行うと
$ : (ls)
-bash: syntax error near unexpected token `ls'
$ echo $?
256
となり、echo
等のコマンドに渡したり代入したりするときのように
$
を付けて実行しないと駄目な模様。
ここまで来て、a++
もサブシェルの中で実行されるから変更があるわけで、
と考えると、インクリメントされた結果はどの位置のものな中、
というものがさらにちょっと特殊でよく分からなくなったのですが、
bashのマニュアルを見てみると
(list)
: listをサブシェルで実行{list;}
: listを現在のシェルで実行((expression))
:ARITHMETIC EVALUATION
に従って評価。let "expression"
と等価。
と言った感じ。これだけ見ると二重括弧((expressionistic))
はサブシェルではないような。
(そもそもコマンド、ではないと思うので)。
さらにa
の変更が返って来て現在のシェルで反映されてる所もちょっと良くわからない所。
というわけで、厳密に何がどうなってるか理解したわけではないんですが、
: $((a++))
とするとa
をインクリメント出来る。a=$((a+1))
と同じ文字数になってしまうがよりシンプル。:
の右側に書いたコマンドはサブシェルを呼ぶようなコマンドだとサブシェル内のコマンドは実行される。
と言うこと。
ちなみに、この:
を用いると、whileでの無限ループが
while :; do echo loop;sleep 10;done
と書けます。良く
while [ 1 ]; do echo loop;sleep 10;done
と言った形を見ますが、大分省略できます。
二重括弧の方のTipとしてはマニュアルにもありますが、
for((i=0;i<10;i++));do echo $i;done
みたいな使い方でCみたいなループを書くことが出来ます。
二重括弧についてさらに
$ a=1
$ ((a++))
$ echo $a
2
こんな感じでインクリメントだけを書けるのは、
元々二重括弧内に式を書くとそれが評価され、
それを$
を前に付けることで中身の結果を取り出すような形なんだと思ってます。
勿論((1+1))
見たいのも書けますが、これだと単にtrueを返すだけ。
これは
$ (ls)
と
$ ls_result=$(ls)
の様な()
の対応と同じ様なこと、と思って良いのかな、と思ってたり?
ただ、(ls)
は単独では結果が表示され、$
をつけるとその結果が
渡される様になるわけで、((1+1))
の様な場合とは
実際に行われている処理は違うっぽいですが。
大分今更ながらなんですが 全体的に何がどうなるかは結構わかった部分が多いものの、 何がどうなってるか全然理解してないところが多すぎ。。。