一組のコマンドを指定された回数だけ実行するのに使われ、 一般書式は次のようになっています。
for val in arg1 arg2doと doneに囲まれたコマンド群がループの本体で、 これらのコマンド群は inの後ろに並べられた引数の数だけ繰返し実行されます。 このループが実行されると最初に arg1の内容が valに、次に arg2 の内容が valにargn
do
commands
![]()
done
、と順次が参照されながら inに続くリストの中身が
空になるまでループ処理が継続します。つまり、 inの後ろに n個の引数があった
ならば n回ループが実行されることになります。
inに続く引数に *, ?, [ ]など
のメタ文字が含まれる場合にはシェルにより展開されてから forループが実行されます。
シェル変数 $* はスクリプトに渡されたすべての引数に対応するために for文と
組み合わせて使うことができます。しかし、実際の使用に当っては少し注意が必要です。
次に示すものはコマンドラインに入力された引数を1行に1個づつ表示させるものです
が、時として期待を裏切ります。
echo "Number of arguments:このスクリプトをfor.shとして実行してみましょう。まずは、$#"
for i in$*
do
echo $i
done
$ for.sh A B Cこれは正常です。ではつぎにAとBを引用符で囲んでみましょう。
Number of argumets: 3
A
B
C
$ for.sh 'A B' Cさて、不思議なことが起こるものです。単一引用符は文字列をシェルから保 護しますから引数は2つ。事実、与えられた引数の数を示すシェル変数
Number of argumets: 2
A
B
C
$# は
間違いなく2と表示されています。なのになぜか3行に出力されてしまいました。
種明かしはこうです。'A B' はシェルから保護されて1つの引数として
スクリプトに渡されます。しかし、保護されるのはコマンドラインでのことであり、
引数としてスクリプトに渡った時には単一引用符が外れています。ですから、
for文で $* が展開された時、 in以降のリストにはAとBを1つにしている単一引
用符がありませんので、
for i in A B Cとなってしまい、ループは3回実行されることになります。 これを回避するために for文には in以降のリストを持たない特別な記述が許されてい ます。for.sh2行目の in以降を省略し、
echo "Number of arguments:としたものです。これで試してみると$#"
for i
do
echo $i
done
$ for.sh 'A B' Cとなるはずです。さらに、特殊なシェル変数
Number of argumets: 2
A B
C
$@ を使うもの1つの方法です。
シェル変数 $* はコマンドラインでの引用符が外された状態の引数を $1, $2,
$3として持っています。この $* の代わりに "$@" を使う
と "$1", "$2", "$3" として置き換えられるために $* で
のような不都合は起こりません。
ただし、二重引用符で囲み "$@" としなければ $* とまったく同じよう
に展開されてしまいます。