Powered by SmartDoc

1 謎の `:' コマンド

sh(1)によれば`:'は"A null command that returns a 0 (true) exit value."とある.つまりカードで言うところの「ババ」である.で,使い方であるが,引数にパラメータ展開,コマンド置換,算術演算表現などを指定して,それだけだと文法上エラーとなることを簡潔に実行させることができる.たとえば変数の初期化だが,

foo=${foo:-bar}

としても良いが,

: ${foo:=bar}

とすればもっと簡潔に書ける.ここで,初期化の方法だが,`:-'ではなく,`:='にすることに注意しないといけない.foo:-barは単にfoobarに置き換えるだけだが,foo:=barは最終的にfoobarが代入されることになる.言葉ではなんとなくしか理解できないが以下の例で見れば明らかになる.

: ${n:=${1:-10}}

これは引数が指定されなければ${1}が10に置き代り,それがnに代入される.つまり,ここでは${1:-10}であって${1:=10}としてはいけないことは明らかであろう(1).次に算術演算だが,最近のsh(2)ではCライクな算術演算子が利用できる.ただし,これは`$((...))'という中でのみ実行でき,もちろんこの演算子自体はいわゆる実行文ではなく参照のみ有効となる.ただし,このまま実行文として使っても文句は言われるが実行はできる.これを「正しく」行なうために`:'の引数として使用するのだ.たとえば

: $((s += i))
: $((i += 1))

とかすれば良い.

ということで, 1 + 2 + 3 + · + n の実行結果を求める

sum [n]

というコマンドは以下のように書ける.

#!/bin/sh
: ${n:=${1:-10}}
s=0
i=1
while [ $i -le $n ]; do
    : $((s += i))
    : $((i += 1))
done
echo $s
  1. つまり関数内での引数の受け渡しパラメータである1という`変数'は基本的に「読み出しのみ」であってこれには書込めないことは自明である.
  2. 何時からかは知らないが,Cの算術演算の全ての演算子が利用できる.