一組のコマンドを指定された回数だけ実行するのに使われ、 一般書式は次のようになっています。
for val in arg1 arg2 argndoと doneに囲まれたコマンド群がループの本体で、 これらのコマンド群は inの後ろに並べられた引数の数だけ繰返し実行されます。 このループが実行されると最初に arg1の内容が valに、次に arg2 の内容が valに、と順次が参照されながら inに続くリストの中身が 空になるまでループ処理が継続します。つまり、 inの後ろに n個の引数があった ならば n回ループが実行されることになります。 inに続く引数に *, ?, [ ]など のメタ文字が含まれる場合にはシェルにより展開されてから forループが実行されます。
do
commands
done
シェル変数 $*
はスクリプトに渡されたすべての引数に対応するために 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
" として置き換えられるために $*
で
のような不都合は起こりません。
ただし、二重引用符で囲み "$@
" としなければ $*
とまったく同じよう
に展開されてしまいます。