平成14年度 専門コア情報処理演習
y
(理学部 数理情報科学科イ組 対象、塩田教官)
y
11月26日の教材
今日はシェルスクリプトを勉強します。
多数のコマンドを連続して繰り返し実行したいときには、 そのコマンドをファイルに書いておくことでまとめて実行することができます。 このファイルに書かれたものをスクリプトと呼びます。
10月8日に lpt というコマンドをつくりました。
#!/bin/csh -f
jtops -s10 -l50 $1 | lp
という内容のテキストファイル lpt を作って
chmod +x lpt
と打つことにより、lpt を実行ファイルに変換したのでした。 今日はこれをもう少し詳しくやります。
□ チクタクコマンド
最初はチクタクコマンドを作ります。
#!/bin/csh -f
sleep 1
echo "Tick"
sleep 1
echo "Tack"
という内容のテキストファイル tick を作って
chmod +x tick
と打ちます。
tick を実行してみましょう。
./tick
1秒後に Tick が現れ、 その1秒後に Tack が表示され、さらにもう1秒たつとコマンドプロンプト に戻ることがわかります。
sleep 1 は 1秒待て、という命令です。
echo は出力命令です。
./ を付けるのはカレントディレクトリにある tick を実行せよ、という意味です。
□ 繰り返し文
while (条件) ... end という書き方を使うと
...
の部分を 繰り返し実行することができます。 条件として 1 は真を表わしますので、 次のようなスクリプトは無限回繰り返されることになります。
#!/bin/csh -f
while (1)
sleep 1
echo "Tick"
sleep 1
echo "Tack"
end
このスクリプトを tk というファイルに作成し、実行してみましょう。
end のあとで改行しておかないと正常に動きませんのでご注意。 (このあとに作るスクリプトも、最終行の後ろに改行を入れてください。)
放っておくといつまででも動いていますので、 中断するには [Ctrl] C を押します。
□ コマンド実行結果の変数への代入
コマンドの実行結果を変数に入れて利用したいことがあります。 このためには
` (back quote, @ のキーのシフト)
でコマンドを囲んでやります。
次の例では date コマンドの結果を変数に入れています。
#!/bin/csh -f
# 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 02ss 1 41
を実行すると
02ss1
02ss2
02ss3
...
02ss41
という出力がされます。
$1, $2, $3 はそれぞれ1番目、2番目、3番目の引数を表します。
@ は計算式を表します。
「 @ i = $2 」は「変数 i に $2 の値を代入せよ」という命令です。 実行例では、最初の i の値は 1 になります。
「 echo "$1$i" 」で $1 の文字列と i の値を続けて出力しています。 実行例では、最初の出力は 01ss1 になります。
「 @ 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 02ss 1 41
を実行すればめでたく
02ss001
02ss002
02ss003
...
02ss041
となります。百の位 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 をつくり scjse に格納しなさい。
あとで皆さんのファイルをチェックして今日の出席に替えます。
□ 発展課題
上の nishin は負の数を入力すると答えを出しません。 これを改良して、負の数を入力すると
./nishin -11
-1011
のように - を付けるように工夫しなさい。
恐らく if 文を使う必要があると思います。 if 文とは
if ( 条件式 ) then
実行文
:
実行文
endif
の形をしていて、条件が真のときに then と endif の間の実行文を実行します。
さらに余裕のある人は、入力された自然数を16進数(10~15 を a~f で表す)に変換して表示するシェルスクリプト hex をつくりなさい。
□ 参考 : foreach 文
foreach i (...)
という書き方では
...
のそれぞれを i という変数に代入して実行します。 変数 i の参照には $i を使います。 また、変数名は i でなくても英文字であればOKです。
#!/bin/csh -f
foreach i (*)
echo "$i :"
head -3 $i
echo
end
というスクリプトを atama という名前のファイルに作成して実行してみましょう。
(*) はカレントディレクトリにあるファイルの名前の一覧を意味し、
echo 文でファイル名前を、
head 文でそのファイルの3行目までを表示しています。
専門コア情報処理演習 '02 のページへ