平成12年度 専門コア情報処理演習
y
(理学部 数理情報科学科イ組 対象、塩田教官)
y
11月28日の教材
今日はシェルスクリプトを勉強します。
多数のコマンドを連続して繰り返し実行したいときには、 そのコマンドをファイルに書いておくことでまとめて実行することができます。 このファイルに書かれたものをスクリプトと呼びます。
10月17日に net というコマンドをつくりました。
#!/bin/csh -f
netscape &
という内容のテキストファイル net を作って
chmod +x net
と打つことにより、net を実行ファイルに変換したのでした。 今日はこれをもう少し詳しくやります。
□ チクタクコマンド
最初はチクタクコマンドを作ります。
#!/bin/csh
sleep 1
echo "Tick"
sleep 1
echo "Tack"
sleep 1
という内容のテキストファイル tick を作って
chmod +x tick
と打ちます。
tick を実行してみましょう。 1秒後に Tick が現れ、 その1秒後に Tack が表示され、さらにもう1秒たつとコマンドプロンプト に戻ることがわかります。
sleep 1 は 1秒待て、という命令です。
echo は出力命令です。
□ 繰り返し文
while (条件) ... end という書き方を使うと
...
の部分を 繰り返し実行することができます。 条件として 1 は真を表わしますので、 次のようなスクリプトは無限回繰り返されることになります。
#!/bin/csh
while (1)
sleep 1
echo "Tick"
sleep 1
echo "Tack"
end
このスクリプトを tk というファイルに作成し、実行してみましょう。
放っておくといつまででも動いていますので、 中断するには Ctrl + C を押します。
□ foreach 文
foreach i (...)
という書き方では
...
のそれぞれを i という変数に代入して実行します。 変数 i の参照には $i を使います。 また、変数名は i でなくても英文字であればOKです。
#!/bin/csh
foreach i (*)
echo "$i :"
head -1 $i
end
というスクリプトを atama という名前のファイルに作成して実行してみましょう。
(*) はカレントディレクトリにあるファイルの名前の一覧を意味し、
echo 文でファイル名前を、
head 文でそのファイルの一行目を表示しています。
□ コマンド実行結果の変数への代入
コマンドの実行結果を変数に入れて利用したいことがあります。 このためには ` (back quote) でコマンドを囲んでやります。
次の例では date コマンドの結果を変数に入れています。
#!/bin/csh
# clk --- banner clock
while (1)
clear
set t = `date +%T`
banner "$t"
sleep 1
end
上のスクリプトを clk という名前で作成し実行してみましょう。
# で始まる行にはコメントを書くことができます。
date +%T が現在の時刻を表示するコマンドで、
banner でそれをバナーに仕立てています。
□ コマンド引数
シェルスクリプトには引数を渡してやることが出来ます。
次の例ではシェルスクリプトが3つの引数 $1,$2,$3 を受け取るようになっています。
#!/bin/csh
@ i = $2
while ( $i <= $3 )
echo $1$i
@ i++
end
上のスクリプトを seq という名前で作成し、
seq 00ss 1 45
を実行すると
00ss1
00ss2
00ss3
...
00ss45
という出力がされます。
$1, $2, $3 はそれぞれ1番目、2番目、3番目の引数を表します。
@ は計算式を表します。
「 @ i = $2 」は「変数 i に $2 の値を代入せよ」という命令です。 実行例では、最初の i の値は 1 になります。
「 echo "$1$i" 」で $1 の文字列と i の値を続けて出力しています。 実行例では、最初の出力は 00ss1 になります。
「 @ i++ 」で変数 i の値が 1 足され、
変数 i の値が $3 以下の間、この作業が繰り返されます。
本当は皆さんのユーザIDを書きたかったので、 001, 002, ... になるように書けば次のようになります。
#!/bin/csh
@ i = $2
while ( $i <= $3 )
@ p = $i / 100
@ q = ( $i / 10 ) % 10
@ r = $i % 10
echo $1$p$q$r
@ i++
end
このように seq を編集し直して
seq 00ss 1 45
を実行すればめでたく
00ss001
00ss002
00ss003
...
00ss045
となります。百の位 p、十の位 q、一の位 r をそれぞれ計算しているところがミソです。
算術式の中では、/ は商を、% は余りを計算します。
□ 今日の課題
次のシェルスクリプトは入力された自然数を2進数に変換して表示します。
#!/bin/csh
@ i = $1
set t = ""
while ( $i > 0 )
@ p = $i % 2
@ i = $i / 2
set t = $p$t
end
echo $t
これを nishin という名前で作成し実行してみてください。
nishin 11
1011
これを参考にして、入力された自然数を3進数に変換して表示するシェルスクリプト sanshin をつくりなさい。
あとで皆さんのファイルをチェックして今日の出席に替えます。
□ 発展課題
上の nishin は負の数を入力すると答えを出しません。 これを改良して、負の数を入力すると
nishin -11
-1011
のように - を付けるように工夫しなさい。
恐らく if 文を使う必要があると思います。 if 文とは
if ( 条件式 ) then
実行文
:
実行文
endif
の形をしていて、条件が真のときに then と endif の間の実行文を実行します。
さらに余裕のある人は、入力された自然数を16進数(10~15 を a~f で表す)に変換して表示するシェルスクリプト hex をつくりなさい。
専門コア情報処理演習 '00 のページへ