シェルスクリプトプログラミング

シェルスクリプトプログラミング
075761G 屋良朝貴
担当教員 當間 愛晃
実験日:5 月 28 日
提出日:5 月 29 日
提出締め切り日:5 月 30 日
1
level1
以下の機能を満たすシェルスクリプトを作成せよ。
• a=6,b=3 とし、四則演算を計算する
• 実行結果は以下のように出力すること
level1 の実行結果
a=6,b=3
a+b=9
a-b=3
a*b=18
a/b=2
======level1.sh======
#!/bin/sh
#引数設定
a=6
b=3
#各種演算
c=‘expr $a + $b‘
d=‘expr $a - $b‘
e=‘expr $a ’*’ $b‘
f=‘expr $a / $b‘
echo ”# Level1 の実行結果”
echo ”a=6,b=3”
echo ”a+b”=$c
echo ”a-b”=$d
echo ”a*b”=$e
echo ”a/b”=$f
===================
level1 の出力結果
# Level1 の実行結果 a=6,b=3
a+b=9
a-b=3
a*b=18
a/b=2
2
考察
‘expr 引数 1 演算子 引数 2‘で演算が可能になる
echo コマンドにより任意の文字列が出力可能
演算子は C 言語等と同じ
level2
以下の機能を満たすシェルスクリプトを作成せよ
• level1.sh を拡張する
• level1.sh では演算対象の a,b をスクリプト内で設定していたが、
この2つの値を実行時の引数から設定する
• 実行結果は以下のように出力する
level2 の実行結果
#参考出力結果 (Level2)
a=8,b=2
a+b=10
a-b=6
a*b=16
a/b=4
#参考出力結果 (Level2)
a=10,b=5
a+b=15
a-b=5
a*b=50
a/b=2
3
=====level2.sh=====
#!/bin/sh
#引数代入設定
a=$1
b=$2
#各種演算
c=‘expr $1 + $2‘
d=‘expr $1 - $2‘
e=‘expr $1 ’*’ $2‘
f=‘expr $1 / $2‘
#引数と演算結果表示
echo ”a=”$1,”b=”$2
echo ”a+b”=$c
echo ”a-b”=$d
echo ”a*b”=$e
echo ”a/b”=$f
===================
level2 の出力結果
引数を 2 個挿入したとき
sh-2.05b$ sh level2.sh 6 3
a=6,b=3
a+b=9
a-b=3
a*b=18
a/b=2
引数を 2 つ以外挿入したとき
sh-2.05b$ sh level2.sh 6
expr: syntax error
expr: syntax error
expr: syntax error
expr: syntax error
a=6,b=
a+b=
a-b=
4
a*b=
a/b=
考察
a=$数字 とすることでコマンドライン上で引数設定ができる
引数をきちんと挿入しなかった場合エラーが表示される。
level3
以下の機能を満たすシェルスクリプトを作成せよ
• int 型の引数を 2 個とり、それぞれ int1、int2 として設定する
• 引数が 2 個以外の場合には使い方を出力して終了する
• int1 と int2 を数値比較し以下のように出力する
prompt > ./level3.sh
Usage: prompt % ./level3.sh int1 int2
prompt > ./level3.sh 10 20
int1=10, int2=20
int1 is less than int2.
prompt > ./level3.sh 10 10
int1=10, int2=10
int1 is equal to int2.
prompt > ./level3.sh 20 10
int1=20, int2=10
int1 is greater than int2.
5
=====level3.sh=====
#!/bin/sh
#引数設定
if [ $# -eq 2 ] ; then
int1=$1
int2=$2
else
echo ”Usage: prompt> ./level3.sh int1 int2”
exit 1
fi
#int1 と int2 が等しいとき
if [ $int1 -eq $int2 ] ; then
echo ”int1=$int1,int2=$int2”
echo ”int1 is equal to int2.”
else
#int1 が int2 より大きいとき
if [ $int1 -gt $int2 ] ; then
echo ”int1=$int1,int2=$int2”
echo ”int1 is greater than int2.”
else
#int1 が int2 より小さいとき
echo ”int1=$int1,int2=$int2”
echo ”int1 is less than int2.”
exit 1
fi
fi
=================
level3 の実行結果
int1 が大きいとき
sh-2.05b$ sh level3.sh 6 2
int1=6,int2=2
int1 is greater than int2.
6
int2 が大きいとき
sh-2.05b$ sh level3.sh 2 6
int1=2,int2=6
int1 is less than int2.
int1 と int2 が等しいとき
sh-2.05b$ sh level3.sh 2 2
int1=2,int2=2
int1 is equal to int2.
引数設定が正しくないとき
sh-2.05b$ sh level3.sh 2
Usage: prompt> ./level3.sh int1 int2
考察
if 文を使用することで C 言語等と同様な動きが可能
大きさを表す評価式を用いることで比較演算ができる
• int1 -gt int2
int1 > int2 と同じ
• int1 -eq int2
int1 = int2 と同じ
• int1 -lt int2
int < int2 と同じ
上記のように比較可能
level4 以下の機能を満たすシェルスクプトを作成せよ
• 指定したディレクトリの内容を表示するコマンド myls.sh を作成せよ
• 指定されたディレクトリが存在しない場合には「Not found: $dir」等
のようにエラーを出力して終了すること
• 指定されたディレクトリ内に存在するディレクトリと通常のファイル
は, 出力を分けて表示すること.
• ディレクトリの後ろには ”/” を表示すること.
7
=====myls.sh=====
#!/bin/sh
if [ -d $1 ] ;then
dir=$1
else
echo ”Not found Dir”
exit 1
fi
#ファイルの取得
filelist=‘ls -1 $dir‘
for file in $filelist
do
#ファイルもしくはディレクトリの出力
if [ -d $dir/$file ] ; then
echo ”$file/”
else
echo ”$file”
fi
done
================
level4 の実行結果
全体の出力
sh-2.05b$ sh myls.sh
CVS DB/
Desktop/
Documents/
Library/
Make/
Movies/
Music/
Pictures/
Public/
Sites/
Test/
daily.gnuplot
download/
8
example1.8.sh
homepage/
makesample/
myls.sh
temp/
test.eps
test.png
zikken/
任意のディレクトリに対しての出力
sh-2.05b$ /bin/ls -FC -/temp
wget-1.11.2/ wget-1.11.2.tar.gz
存在しないとき
sh-2.05b$ sh myls.sh -/tes
Not found Dir
考察
do ... done を用いることでループができる
場所を指定することにより指定したディレクトリの内容を表示する
9
level5
以下の機能を満たすシェルスクリプト myupper.sh を作成せよ
• 指定されたファイル名を小文字から大文字に変換する
=====myupper.sh=====
#!/bin/sh
#ファイル取得
filelist=$*
for file in $filelist
do
if [ -f $file ] ; then
echo ”存在します”
#文字変換
newfile=‘echo $file | tr [a-z] [A-Z]‘
#ファイルの上書き
mv $file $newfile
else
echo ”存在しません”
fi
done
==================
level5 の実行結果
sh-2.05b$ ls
example1.5.sh hello.sh mymv.sh up2html.sh
example1.7.1.sh ifconfig.pdf level2.sh myupper.sh
example2.sh level1.sh level3.sh text.rtf
sh-2.05b$ sh myupper.sh text.rtf
存在します
sh-2.05b$ ls
TEXT.RTF example2.sh level1.sh level3.sh
example1.5.sh hello.sh mymv.sh up2html.sh
example1.7.1.sh ifconfig.pdf level2.sh myupper.sh
10
存在しないとき
sh-2.05b$ sh myupper.sh tet.rtf
存在しません
考察
実行結果より任意のファイルが大文字に変換されている
‘echo $file | tr [a-z] [A-Z]‘を用いることで文字列が大文字に変更される
‘echo $file | tr [A-Z] [a-z]‘を用いることで文字列が小文字に変更される
level6 以下の機能を満たすシェルスクリプト mymv.sh を作成せよ
• 第 1 引数で指定された拡張子を持つファイルに対し、拡張子を第 2 引
数に変換するスクリプトを作成せよ
=====mymv.sh=====
#!/bin/sh
if [ $# -eq 2 ] ; then
arg1=$1
arg2=$2
else
echo ”Not found”
exit 1
fi
files=‘ls -1 *.$arg1‘
echo $files
for file in $files
do
newfile=‘basename $file $arg1‘$arg2
echo $newfile
done
mv $file $newfile
=================
11
level6 の実行結果
sh-2.05b$ ls
TEXT.RTF ifconfig.pdf mymv.sh
RTF から pdf に変更 sh-2.05b$ sh mymv.sh RTF pdf
TEXT.RTF
TEXT.pdf
sh-2.05b$ ls
TEXT.pdf ifconfig.pdf mymv.sh
考察
実行結果より任意の拡張子のみ変更が行われている
‘basename $file $arg1‘$arg2 について
$file — ファイル名
$arg1 — 第 1 引数 (変更元の拡張子)
$arg2 — 第 2 引数 (変更指定の拡張子)
level7
gnuplot をスクリプトファイルを通して利用せよ
• 条件 0—gnuplot へのコマンド受け渡しをスクリプトファイルとすること
• 条件 1—数値データ数を 10 件以上とすること
• 条件 2—LATEX の出力に含めるため,gnuplot の出力画像形式を EPS 形
式とすること
• 条件 3—字句の説明やグラフのタイトルを図内に含めること
12
The annual Income and Expenditure (Unit:thousand)
10
Income and Expenditure
"data2.rtf" using 1:2
5
0
-5
0
1
2
3
4
5
6
7
8
9
Month
=====gnup2.sh=====
#!/bin/sh
gnuplot << EOF
set terminal postscript eps
set output ”test2.eps”
set xlabel ”Month”
set ylabel ”Income and Expenditure”
set title ”The annual Income and Expenditure (Unit:thousand)”
set xrange [0:13]
set yrange [-5:10]
set xtics 1
set mxtics 0
set ytics 5
set mytics 5
set grid xtics ytics mxtics mytics
plot ”data2.rtf” using 1:2 with boxes
EOF
=================
13
10
11
12
13
考察
gnuplot は棒グラフや折れ線グラフ等を用いる場合
set xrange [0:13] とすることで x の範囲を
set yrange [-5:10] で y の範囲をそれぞれ指定できる。
このグラフは、自分自身のデータをグラフ化しているため、数値は分かりや
すいように調整しています
感想
今回の課題は、大変難しいものだった。前半は演算が多かったので簡単だった
が、後半は if 文を用いたりしたので、とても苦戦した。特に、level7 の gnuplot
の問題は難しかったが、gnuplot の使い方が分かるようになったりと得られ
るものもあった。難しい課題ではあったが、シェルスクリプトは、ほぼ分か
るようになった。
参考文献
LaTeX コマンドシート一覧 [http://www002.upp.so-net.ne.jp/latex/]
Gnuplot 入門 第 0.08 版 [http://dsl4.eee.u-ryukyu.ac.jp/DOCS/gnuplot/gnuplot.html]
14