システムプログラミング
担当:青木義満
情報工学科
3年生対象 専門科目
第
4, 5回
シェルとは?
• ユーザーとUNIXシステムの間のインタフェー
スとして機能するプログラム
• カーネルで行われる処理の細かな部分を
ユーザーから隠す役割
カーネル csh その他の プログラム 表2.1プログラミング言語としてのシェル
• シェルプログラム作成の2つの方法
– コマンドを入力してシェルによって対話的に実行
– コマンドをファイルに保存し,プログラムとして呼び出す
• 対話的プログラムの例
– grep –l POSIX * | more
– POSIXというパターンに一致する内容を持つファイルの名
前を出力
– いつもコマンドを打つのは面倒
シェルプログラミングの利点
• 豊富なUNIXコマンド群を有効活用
• 例えば….
– ディレクトリ内にある画像ファイル全てに対して,
プログラムによりある処理を施したい
• ディレクトリ内にある画像ファイルのみを抽出,繰り返し
演算
– 複数あるデータベースファイルから,ある特定の
文字列を含むファイルのみを抽出してプログラム
により処理したい
シェルスクリプトの作成
• コマンドを記述したファイル”first.sh”を作成
#!bin/sh #first.sh
#This file looks through all the files in the current
#directory for the string “yamada”, and then prints those #files to the standard output.
for file in * do
if grep -q yamada $file then
more $file fi
done exit 0
シェルの構文
• シェルの持つ強力なプログラミング機能の学習
• 小さなプログラムの断片を対話的にテスト,大きなスクリプトに
組み込める
• 構造化されたプログラムの作成
• 学習項目
– 変数:文字列,数値,環境,パラメータ
– 条件:シェルのブール型
– プログラム制御:if, elif, for, while, until, case
– リスト
シェルの変数
• 変数を宣言せずに使用
– 変数を最初に使用した時点で変数が作成
• デフォルトでは,全ての変数が文字列型
• 大文字と小文字は区別(例:FOOとfooは別)
• 変数名の前に$文字をつけることで変数の内容を取
得
• echoコマンドで変数の内容を出力
• 変数に値を割り当てる場合以外には$をつける必要
変数の使用例
bash-2.05$ salutation
=
Hello
bash-2.05$ echo
$
salutation
bash-2.05$ salutation=“Yes Dear”
bash-2.05$ echo
$
salutation
bash-2.05$ salutation=7+5
bash-2.05$ echo
$
salutation
空白を含む文字列は引用符で囲む必要がある
また,等号の両側に空白をいれてはいけない
#!bin/sh myvar="Hi there" echo $myvar echo "$myvar" echo '$myvar' echo \$myvar
echo Enter some text read myvar
echo '$myvar' now equals $myvar exit 0
read コマンド
環境変数
• いくつかの変数は,あらかじめ環境に含まれている値
で初期化(環境設定)
• 大文字の変数
例題)パラメータと環境変数
!/bin/sh
salutation="Hello" echo $salutation
echo "The program $0 is now running" echo "The second parameter was $2" echo "The first parameter was $1" echo "The parameter list was $*"
echo "The user's home directory is $HOME" echo "Please enter a new greeting"
read salutation echo $salutation
条件
• 条件を調べ,その結果に応じて異なる処理をする機
能
◆
test( [ ] )コマンド
– シェルで真偽を判定するための[ ]コマンド(testコマンド)
– testコマンドにより単純な条件を調べる
– ファイルが存在するかどうか?
if test -f fred.c
then
・・・・・・・
fi
[ -f fred.c ]
スペースが必要!簡単な
testコマンドの使用例
#!/bin/sh
if test -f fred.c
then
echo "File fred.c exists."
else
echo "File fred.c not found."
fi
testコマンドで使用でき
る条件
制御構造
◆
if ステートメント
使用方法
if
condition
then
statements
else
statements
if コマンドの使用例
• ファイル名:if1.sh
#!/bin/sh
echo "Is it morning? Please answer yes or no"
read timeofday
if [ $timeofday = "yes" ]; then
echo "Good morning"
else
echo "Good afternoon"
fi
Ifコマンド2
• ファイル名:if2.sh
!/bin/sh
echo "Is it morning? Please answer yes or no"
read timeofday
if [ $timeofday = "yes" ]; then
echo "Good morning"
elif [ $timeofday = "no" ]; then
echo "Good afternoon"
else
Ifコマンド3
• ファイル名:if3.sh
!/bin/sh
echo "Is it morning? Please answer yes or no"
read timeofday
if [
“
$timeofday
”
= "yes" ]; then
echo "Good morning"
elif [
“
$timeofday
”
= "no" ]; then
echo "Good afternoon"
else
echo "Sorry, $timeofday not recognized. Enter yes or no"
exit 1
繰り返し制御
• for, while, case文(Cとは少し異なる)
◆
forの構文
for
variable
in
values
do
statements
変数 任意の文字列集合
for文の使用例1
• ファイル名:for1.sh
#!bin/sh/
for
name
in
aoki tokunaga ohzeki 43
do
echo $name
done
for文使用例2
(ワイルドカードの展開 重要)
• ファイル名:for2.sh
#!bin/sh/
for
file
in
$(ls *.c)
; do
echo $file
done
ワイルドカードWhile文
• for文:一連の文字列を対象として繰り返し処
理をするには便利.指定した回数だけコマン
ドを実行する場合は? また,繰り返す回数
が不明の時は?
• 例:10回の繰り返し
#!/bin/sh
for foo in 1 2 3 4 5 6 7 8 9 10
do
echo "here we go again"
While文の構文
◆
while
while
condition
do
statements
done
繰り返しの条件 コマンドwhile文使用例1
(パスワードの入力を求めるスクリプト)
• ファイル名:while1.sh
#!bin/sh
echo "Enter your password" read trythis
while [ "$trythis" != "secret" ] do
echo "Sorry, try again" read trythis
done
while文の使用例2
(繰り返しの実行)
• ファイル名:while2.sh
#!/bin/sh
i=1
while [ "$i" -le 10 ]
do
echo "Loop number : $i"
i=$(($i+1))
case文
◆
case
case
variable
in
pattern | pattern | …. )
statements1
;;
pattern | pattern | …. )
statements2
;;
…..
esac
case使用例1
(ユーザーからの入力)
• ファイル名:case1.sh
#!/bin/sh
echo "Is it morning? please answer yes or no" read timeofday
case "$timeofday" in
"yes") echo "Good morning";; "no") echo "Good afternoon";; "y") echo "Good morning";; "n") echo "Good afternoon";;
case使用例2
(パターンをまとめる)
• ファイル名:case2.sh
#!/bin/sh
echo "Is it morning? please answer yes or no" read timeofday
case "$timeofday" in
"yes" | "y" | "Yes" | "YES") echo "Good morning";; "no" | "n" | "No" | "NO") echo "Good afternoon";; *) echo "Sorry, answer not recognized.";;
esac exit 0;
case使用例3
(複数ステートメントの実行)
• ファイル名:case3.sh
#!/bin/sh
echo "Is it morning? Please answer yes or no" read timeofday
case "$timeofday" in
"yes"|"y"|"Yes"|"YES")
echo "Good Morning"
echo "Up bright and early this morning" ;;
[nN]* )
echo "Good Afternoon" ;;
*)
シェルスクリプト演習問題
• ディレクトリ内のファイルの中から,拡張子が
*.txtのファイルのみを表示し,その個数を表
示するシェルスクリプトを作成せよ
リスト(
And と Or)
• ANDリスト
statement1 && statement2 && statement3 …
左から順に実行(
falseとなるまで)
• Orリスト
statement1 || statement2 || statement3 …
左から順に実行(trueとなるまで)
リストの例
#!/bin/sh
touch file_one rm -f file_two
if [ -f file_one ] && echo "hello" && [ -f file_two ] && echo "there"
then
echo "in if" else
echo "in else" fi
exit 0
#!/bin/sh
rm -f file_one
if [ -f file_one ] || echo "hello" || echo "there"
then
echo "in if" else
echo "in else" fi
exit 0
関数
• 関数の定義
function_name( ){
statements
}
#!bin/sh foo(){echo "Function foo is executing" }
echo "script starting" 簡単な関数の
使用例
ローカル変数の使用
#!/bin/sh
sample_text="global variable" foo(){
local sample_text="local variable" echo "function foo is executing" echo $sample_text
}
echo "script starting" echo $sample_text
foo
echo "script ended" echo $sample_text
関数の使用例
#!/bin/sh yes_or_no(){
echo "Parameters are $*" while true
do
echo "Enter yes or no" read x
case "$x" in
y | yes ) return 0;; n | no ) return 1;;
* ) echo "Answer yes or no" esac
done }
echo "Original parameters are $*" if yes_or_no "Is your name $1" then
echo "Hi $1" else
echo "Never mind fi
配列について
• 以下の説明を参照
シェルプログラミング 演習課題
1.ファイル名をシェルの引数[filename]で与え, % /bin/sh judge.sh [filename]
・そのファイルが存在すれば,ファイルの中身を表示する ・存在しない場合には,
"WARNING! No such file [filename]" と表示し, "Enter Filename: " として再度ファイル名の入力を促し,判定を繰り返すシェルプログラムを作成せよ。 2.1のプログラムに,引数の個数チェックを行う処理を追加せよ。 例) % /bin/sh judge.sh → 引数は0 この場合の実行結果