Comments
Description
Transcript
電子計算機及び実習 第 8回 (12/1) 8 シェルスクリプト
8 シェルスクリプト 2008 年度 電子計算機及び実習 55 電子計算機及び実習 第 8 回 (12/1) シェルスクリプト 8 8.1 今日のテーマ * シェルスクリプト ** 今日の提出課題 以下のファイルを添付して,s-suzuki あてに署名をつけて送信せよ.ただし,Subject は 「学籍番号+Dec01」 とせよ.また,メールの本文に添付したファイルの名前を明記すること. 1. kadai8-1.sh 課題 8.1 で作成されたもの. 2. kadai8-3.sh 課題 8.3 で作成されたもの. 3. kadai8-5.sh 課題 8.5 で作成されたもの. 8.2 シェルスクリプト シェルスクリプトとは,シェルの内部コマンド・UNIX のコマンドを組み合わせて,一連の処理を実行するた めに書かれる一種のプログラムである. ホームディレクトリのすぐ下に,script という名前のディレクトリを作成し,今回作成するシェルスクリプト は全てそのディレクトリに保存するようにすること. 最も基本的なシェルスクリプトはバッチ処理と呼ばれるもので,複数のやりたい命令を,その順番に記述した 手順書である.まず,その例から始めることにしよう41 . ¶ test0.sh ³ #!/usr/bin/bash # これはシェルスクリプトの例です. echo "This is my first shell script." echo ----------- calendar -----------cal echo --------------------------------µ ´ このシェルスクリプトを実行してみよう.その方法は 2 つある. 1. % bash ./test0.sh 2. % chmod 700 ./test0.sh % ./test0.sh 両方の方法を試してみよう.2 番目の方法は,test0.sh というスクリプトに実行権限を与えて,あたかも一つの 新しいコマンドであるかのようにする方法になっている.UNIX システムには,このようにして作られたコマン ドもたくさんある. では,test0.sh の内容を見ていこう.第 1 行目ではそれ以降のスクリプトの本文を処理させるプログラムを指 定する.第 2 行目以降の# はコメントを表す.echo は文字列を出力するコマンドであり,cal はカレンダーを出 力させるコマンドである.第 3 行目以降は,やらせたい命令を順に出力している. 課題 8.1 現在の時刻と quota の出力結果を順に出力するシェルスクリプト kadai8-1.sh を作り,実行しなさい. 41 この講義では,いくつかの理由から,bash によるシェルスクリプトを紹介する.普段ログインシェルとして用いている,tcsh (csh) に よってもシェルスクリプトを記述することが可能だが,その文法は bash のものと大きく異なるので注意を要する. 8 シェルスクリプト 2008 年度 電子計算機及び実習 56 バッチ処理だけでは,それほど複雑な処理を実行することはできないが,シェルには,変数・条件判定・繰り 返し処理・関数といったプログラム作成に必要な機能が備わっており,アイディア次第でかなり複雑な処理を実 行するシェルスクリプトが作成できる.条件判定と繰り返し処理はまとめて制御構造と呼ばれることもある.以 下では,変数と制御構造について簡単に説明しながら,いくつかのシェルスクリプトを作成してみよう.シェル スクリプトについて,関数の利用等,より高度なことについては,ウェブ上の情報や書籍を参照して欲しい. 変数(シェル変数) ¶ test1.sh 変数はユーザが任意に設定できる.以下の例を入力・実行してみよ. ³ #!/usr/bin/bash # 変数の設定,参照の例 comment="計算例" i=1 j=2 let k=$i+$j let l=$i*$j echo $comment echo "i= " $i, "j=" $j, "i+j=" $k, "i*j=" $l µ ´ 実行してみればわかるように,4 行目から 6 行目までで変数の設定を,8 行目,9 行目で変数の足し算・掛け算 を,11 行目,12 行目で出力を行っている.変数の値を参照するときには,変数名に $ 記号を付ければよい.ま た,変数の足し算・掛け算を行うための bash のコマンドが let である. 条件判定 ある条件が満たされているとき(あるいは満たされていないとき)のみ,ある処理を実行したいこと がしばしばある.たとえば,あるファイルが存在したらそのファイルを消去したい,といったことである.この ためのシェルスクリプトの仕組みが条件判定である.条件判定の書式は,以下のようなものである: ¶ ³ [ 条件式 ] µ ´ 使用できる条件式の構文を表 1 にまとめておく.以下は具体例である. ¶ test2.sh ³ #!/usr/bin/bash echo "val1=?" read val1 if [ $val1 -gt 5 ] then echo "$val1 is greater than 5." else echo "$val1 is less than or equal to 5." fi µ この例では,read $val1 で,標準入力(キーボード)から変数 $val1 に値(整数値を入れること)を読みこ み,if[ $val1 -gt 5 ] で 5 より大きいかどうかを判別して,その結果が真なら, $val1 is greater than 5. を出力し,偽なら,$val1 is less than or equal to 5. を出力している. ´ 8 シェルスクリプト 2008 年度 電子計算機及び実習 57 ¶ test3.sh ³ #!/usr/bin/bash if [ -e $1 ] then echo "file $1 exists!" else echo "file $1 does not exist!" fi µ ´ この例は,実行時の引数にファイル名を指定し,それが存在するかどうかを判定し,その結果を出力するシェル スクリプトである.変数 $n (n=0,1,2,...) にはシェルスクリプト実行時のコマンドライン引数が設定されてて いる.$0 にはシェルスクリプトの名前が入り,$1 には 1 番目の引数が入る.if [ -e file name] は,file name というファイルが存在すれば真,存在しなければ偽となり,真の場合 then から else までが,偽の場合 else か ら fi までが実行される.なお,このシェルスクリプトを実行するには,test3.sh に実行パーミッションを与え た上で,以下のようにすればよい. ¶ ³ % ./test3.sh file name µ ´ 表 1: 条件式の構文 文字列比較 整数比較 ファイルに関する条件 繰り返し処理 string1 = string2 string1 と string2 が同じなら真 string1 != string2 -n string -z string string1 と string2 が異なるなら真 string が空でないなら真 string が空なら真 n1 -eq n2 n1 -ne n2 n1 -gt n2 n1 と n2 が等しいなら真 n1 と n2 が異なるなら真 n1 が n2 より大きいなら真 n1 -ge n2 n1 -lt n2 n1 が n2 より大きいか等しいなら真 n1 が n2 より小さいなら真 n1 -le n2 n1 が n2 より小さいか等しいなら真 -d file -e file file が存在し,ディレクトリなら真 file が存在するなら真 -s file -r file -w file file が存在し,サイズが 0 でないなら真 file が存在し,読み込み可能なら真 file が存在し,書き込み可能なら真 -x file file1 -nt file2 file が存在し,実行可能なら真 file1 が file2 より新しいなら真 file1 -ot file2 file1 が file2 より古いなら真 似たような処理を何回も繰り返し実行したいこともよくある.そのための仕組みが繰り返し処理 である.シェルスクリプトの繰り返し処理にはいくつかの構文があるが,ここでは while を用いるものを紹介し よう.while を用いた繰り返し処理の構文は以下のようなものである: ¶ ³ while 条件式 do command ... done µ ´ 8 シェルスクリプト 2008 年度 電子計算機及び実習 58 これは,条件式が成立する限り,命令 command を実行する.以下,具体例で見ていこう. ¶ test4.sh ³ #!/usr/bin/bash i=1 while read str do echo "$i:$str" let i=$i+1 done µ ´ この例は,標準入力から入力された文字列に,番号を付けて標準出力に出力している.リダイレクト (<) によっ て,あるテキストファイルを入力すれば,各行に行番号を付して出力するコマンドになる.while read str は変数 str に標準入力から文字列を読み込む作業をあらわし,そが真である限り(読み込める限り),do から done の間 の命令が実行されることになる. なお,このシェルスクリプトを実行するには,test4.sh に実行パーミッションを与えた上で,次のようにすれ ばよい. ¶ ³ % ./test4.sh < file name µ ´ また,file name1 に行番号を付したものを file name2 として保存するには,リダイレクト (>) を用いて次のよう にすればよい. ¶ ³ % ./test4.sh < file name1 > file name2 µ ´ 次の例は,一定の回数,似通った処理を繰り返すための書式を表している. ¶ test5.sh ³ #!/usr/bin/bash i=1 j=0 while [ $i -le $1 ] do let i=$i+1 let j=$j+$2 echo $j done µ ´ これの実行例は以下のようなものである: ¶ ³ % ./test5.sh 10 3 µ ´ 課題 8.2 test1.sh から test5.sh を作成し,それらを実行してみよ. 課題 8.3 以下のような,2 のベキを出力するシェルスクリプトを作成せよ.さらに,引数に 2 つの整数値 a, b を 入力すれば,ベキ ab を出力するシェルスクリプト kadai8-3.sh を作成せよ. 2^1 = 2 2^2 = 4 2^3 = 8 8 シェルスクリプト 繰り返し処理 2 ¶ 2008 年度 電子計算機及び実習 59 繰り返し処理を行う別の構文を紹介しよう.構文は以下のようなものである. ³ for 変数 in arg ... do command ... done µ ´ ここで,arg ... は引数の列であり,for は arg を変数に代入して命令 command を実行し,引数列を全て処理す ると done の次の行に抜ける.具体的な例を一つあげておこう.$@は実行時のコマンドライン引数が全て入る. ¶ ³ test6.sh #!/usr/bin/bash s=0 for i in $@ do echo $i let s=$s+$i done echo $s µ ´ これの実行例は以下のようなものである: ¶ ³ % ./test6.sh 1 2 3 4 µ ´ 課題 8.4 test6.sh を作成し,実行してみよ. 簡単な応用として,カレントディレクトリにある全ての TEX ファイルの文字コードを EUC コードに変換す るためのシェルスクリプトを作ってみよう.例えば,以下のようにすればいいだろう: ¶ test7.sh ³ #!/usr/bin/bash for i in *.tex do echo $i cp $i $i.org nkf -e $i > $i.e mv $i.e $i done µ ´ 念のため,命令の意味を解説しておく.echo $i でファイルの名前を表示する.cp $i $i.org で file name.org の名前でバックアップファイルを作る.nkf -e $i > $i.e で文字コードを EUC コードに変更したものをファ イル file name.e に保存する.最後に mv $i.e $i で file name.e を元のファイル名に戻す. 課題 8.5 ~/jwww/ にある全ての HTML ファイルのパーミッションを 644 に変更するシェルスクリプト kadai8-5.sh を作成せよ. 8 シェルスクリプト 2008 年度 電子計算機及び実習 60 課題 8.6 (チャレンジ問題) 以下のような,9 × 9 の掛け算表 (九九の表) を出力するシェルスクリプトを作成せ よ.さらに,引数に整数値 n を入力すれば,n × n の掛け算表を出力するシェルスクリプト kadai8-6.sh を作 成せよ. 1 2 2 4 3 4 5 6 9 12 15 18 21 24 27 8 12 16 20 24 28 32 36 10 15 20 25 30 35 40 45 6 7 12 14 18 21 24 28 30 35 36 42 42 49 48 56 54 63 8 9 16 18 24 27 32 36 40 45 48 54 56 63 64 72 72 81 8.3 3 6 4 8 5 6 7 8 10 12 14 9 16 18 本日の課題 以下のファイルを添付して,s-suzuki 宛に署名をつけて送信せよ.ただし,Subject は 「学籍番号+Dec01」と せよ.また,メールの本文に添付したファイルの名前を明記すること. 1. kadai8-1.sh 課題 8.1 で作成されたもの. 2. kadai8-3.sh 課題 8.3 で作成されたもの. 3. kadai8-5.sh 課題 8.5 で作成されたもの. 8.4 次回のテーマ 表計算,数式処理.