9. ループ¶
9.1. whileブロック¶
whileブロックは、コマンドが0以外の終了ステータスを返すまで、 無限にブロック内の制御を繰り返します。
9.1.1. シンプルな使い方¶
この例は、dateにUnix時刻を吐かせて、5で割り切れる数になったらループを抜ける処理です。 testコマンドが0でない終了ステータスを返したのを受けてループが終わって最終行のechoが実行されます。
Fig.: simple_while.glue
1 2 3 4 5 6 7 8 9 | import PATH
while
str t = date '+%s' >>= awk '{print $1%5}'
echo t
test t -ne 0
sleep 1
echo 'end'
|
1 2 3 4 5 6 | $ glue ./simple_while.glue
2
3
4
0
end
|
9.1.2. sh系のシェルのwhileのような使い方¶
shやbashのように、 while <コマンド> ; do <処理> ; done と書く場合、つまりコマンドの終了ステータスで処理を実行するかしないかを決めるときは、1段インデントが深くなりますが、次のように記述できます。 1段目のインデントが条件、そのあとのdoブロックが実行したい処理になります。
Fig.: while_do.glue
1 2 3 4 5 6 7 8 9 | import PATH
while
str t = date '+%s' >>= awk '{print $1%5}'
test t -ne 0 ?> do
echo t
sleep 1
echo 'end'
|
実行すると、Unix時刻が5で割り切れる時にdoブロックの中身がスキップされて実行されません。
1 2 3 4 | $ glue ./while_do.glue
3
4
end
|
ネストが2段になりますが、shやbashのwhileよりも長く条件となるコマンドが書けます。 while hogehoge ; do …という書き方が、 hogehogeという部分をコマンドだと気づかない初心者を量産しており悪い影響を与えているので、 踏襲はしていません。
また、 ?>
でエラーが起きたときは、スクリプトが即時に止まります。
終了ステータスは(この例では表示されていませんが)8です。
Fig.: while_do.glueのthenの後にfalseを挟んで実行した時の様子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | $ glue ./while_do_error.glue
Execution error at line 3, char 1
line3: while
^
line4: str t = date '+%s' >>= awk '{print $1%5}'
line5: test t -ne 0 ?> do
line6: false
line7: echo t
line8: sleep 1
line9:
Command error
process_level 0
exit_status 8
pid 5016
|
9.2. foreachブロック¶
bashのwhileは標準入力から字を受け付けますが、 GlueLangではforeachブロックがこの機能を持っています。 readと組み合わせると次のように使えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 | ###こんなスクリプト###
$ cat hoge.bash
#!/bin/bash
seq 1 3 |
while read a ; do
echo "@" $a
done
###こんな出力###
$ ./hoge.bash
@ 1
@ 2
@ 3
|
GlueLangでは、foreachブロックを使うことで、 同様の処理が実装できます。 次の例のように、argv配列に読み込んだ文字列が格納されます。
Fig.: foreach_simple.glue
1 2 3 4 5 6 7 8 9 10 11 | import PATH
#一つずつ数字をforeachに入力
seq 1 3 >>= foreach
echo '@' argv[1]
#2列でforeachに入力
seq 1 4 >>= xargs -n 2 >>= foreach
str f1 = echo argv[1]
str f2 = echo argv[2]
echo f1 f2
|