授業資料/07 の変更点


#CONTENTS

//  第 7 回 -- シェルスクリプト

* What are shell scripts?: シェルスクリプトとは [#t4d39101]

[[&ref(/materials/JNorth_arrow-right-sm.png); スクリプトファイルのコマンド化>授業資料/06#script-command]] を利用して,シェルの操作を一つのコマンドに変えるものである.
&br;
Unix で何回も似たような作業をするときなどには,非常に威力を発揮する.

&br;&br;
CENTER:&size(24){''繰り返す操作はシェルスクリプトで''};
&br;
CENTER:&size(24){''コマンドにしてどんどん効率よく!!''};
&br;&br;

シェルの文法に関しては,sh 系シェルと csh 系シェルで結構違う.
&br;&br;

- csh 系の方が人間にとって直感的.
- bsh 系の方がきちんとしている (&ref(/materials/warning.png); "有害な csh プログラミング" という文言をwebで検索してみよう)

&br;&br;
今回は bsh 系で学習しておく.

&br;&br;
* Preparation and rough explanation: 準備と一連の流れ [#ofe5e489]

** Preparation: 準備 [#w2ab7889]

+ スクリプトファイルを貯蔵しておくディレクトリを用意.
bin という名前を用いることが多い.
&br;
> ''cd␣~''
> ''mkdir␣bin''
<
&br;
+ 用意したディレクトリに path を通す..profile の中で設定するのが良いだろう.
具体的には,~/.profile の中のそれっぽいところに
// programu source 表記
#highlighter(language=SH,number=on,cache=on){{
if [ -d $HOME/bin ]
  then
  PATH=$PATH:$HOME/bin; export PATH
fi
}}
などと書き込んでおけば,次回ログイン時よりこれが有効になる.
&br;
&ref(/materials/warning.png); ''['' や '']'' の前後に入っているスペースを除去しないこと! これらは一文字だが,コマンドなのだ.
&br;
&ref(/materials/warning.png); この変更を有効にするためにいったんログアウトしてから再ログインしてもよいが,
> ''source&#9251;~/.profile''
<
と入力するとその場で''.profile''ファイルの中身が反映されるのでそれでもよい.

&ref(/materials/notes.png); 実習: 上の準備 1, 2 をしておこう.
ただし,阪大の環境では再ログインした時に .profile の内容が反映されないかもしれない.
その場合は,ログインしたら上の''source''を使う方法で path を(毎回?)再設定しよう.

** Rough explanation: シェルスクリプト利用の一連の流れ [#flow-of-shell-scripts]

シェルスクリプトを作って,そして使うにはいつも以下の二段階を踏んでおけば良い.

+ シェルスクリプトを作り,1 で用意したディレクトリに置く.
&br;&br;
+ スクリプトファイルに実行許可を与える.
&br;
例えば,スクリプトファイルが dummy という名前ならば
> ''chmod&#9251;u+x&#9251;~/bin/dummy''
<
とすれば良い.

&br;&br;
* Basic structure of shell scripts: シェルスクリプトの基本構造(bash) [#b42f7907]

[[&ref(/materials/JNorth_arrow-right-sm.png); スクリプトファイルのコマンド化>授業資料/06#script-command]] を用いてシェルスクリプトは作成される.  
スクリプトの先頭行にどう書くかであるが,linux 系であれば 
// シェルスクリプトはシェル設定ファイルを読まないようにした方が安定して動作すること,
// なるべく普遍的な環境で動作すること,非対話環境であること,
// を考慮すると,結論から言えば
// &br;
// &br;
// ''#!/bin/bash --noprofile --posix''
// &br;
// &br;
// と書くか,

> ''#!/bin/sh''

と書けば良いだろう.

&br;
&br;
&ref(/materials/warning.png); スクリプトの内容を実行しないで,文法チェックだけ行いたい場合は,

> ''#!/bin/sh&#9251;-n''

と先頭行に書けばよい.
ファイルの削除など,やや危険な作業を行うスクリプトはこれでチェックすると良いだろう.

&br;&br;
&ref(/materials/warning.png); 実行時にスクリプトの内容も表示したい場合は,

> ''#!/bin/sh&#9251;-v''

と先頭行に書けばよい.
スクリプトの動作が望みのものと違う時はこれでチェックすると良い.

&br;&br;
&ref(/materials/notes.png); 実習

+ Hello というファイル名で,次のような中身のスクリプトを作る.
#highlighter(language=SH,number=on,cache=on){{
#!/bin/sh
echo "Hello, world!"
}}
&br;
+ 上の[[&ref(/materials/JNorth_arrow-right-sm.png); 一連の流れ>#flow-of-shell-scripts]]の 1,2 相当を行おう.
&br;&br;
+ どのディレクトリからでもよいので,
//
>''Hello''
<
と打ち込んで,作成したシェルスクリプトが動作することを確認しよう.

&br;&br;
* Continuous execution of commands: コマンドの連続実行 [#s6da0023]

コマンドの連続実行等について
[[&ref(/materials/JNorth_arrow-right-sm.png); 連続実行>授業資料/01#execution-multiple-commands]]
の部分で学習したが,ここで情報を追加しておく.

: ''コマンド1&#9251;;&#9251;コマンド2'' |
コマンド1 を実行後,コマンド2 を実行する.
: ''( コマンド1&#9251;;&#9251;コマンド2 )'' |
コマンド1 を実行後,コマンド2 を実行する… のだが,
これら二つのコマンドを「サブシェル」のもとで実行する(グループ化).
サブシェルで行った環境変更はもとのシェルに影響しない.
よって,状態を一時的に変更して作業するときに便利.
&br;&br;
&ref(/materials/Gnome-Preferences.png); グループ化の例.&br;
例えば,
//
> '' (cd&#9251;/tmp;&#9251;ls&#9251;-a) ''
<
とすると,/tmp で作業が行われるが,終わったあとにディレクトリは変更されていない.
&br;&br;
また,グループ化したコマンドの標準出力等は「合わさって」出てくる.
これが便利なことも多い.
&br;&br;
&ref(/materials/Gnome-Preferences.png); グループ化の例2.&br;
例えば,
//
> '' (\ls&#9251;/tmp;&#9251;\ls&#9251;/var)&#9251;|&#9251;less ''
<
とすると,/tmp と /var の2つのディレクトリにあるファイルのリストを一度に閲覧できる.
: ''コマンド1&#9251;&amp;&amp;&#9251;コマンド2'' |
AND 実行.
コマンド1 を実行してみて,コマンド1 が成功したならば(エラーにならない時),
コマンド2 を実行する.
: ''コマンド1&#9251;&brvbar;&brvbar;&#9251;コマンド2'' |
OR 実行.
コマンド1 を実行してみて,コマンド1 が失敗したならば(エラーになった時),
コマンド2 を実行する.

&br;&br;
* Grammer of shell scripts: シェルスクリプトの文法 [#k9226a44]

** Comment out: コメントアウト [#qe0a41d2]

シェルスクリプト中で ''#'' という文字があると,
そこから行末までがコメントとして取り扱われる(ただし,文字列中は除く).

** Variables: 変数 [#a44f6532]

[[&ref(/materials/JNorth_arrow-right-sm.png); シェル変数>授業資料/04#shell-variables]]
で学んだとおりに,シェルスクリプトで変数が使える.

&ref(/materials/warning.png); 変数設定のとき,変数名と「=」の間にスペースを入れるな!

&br;
&ref(/materials/warning.png); 実は,変数参照の際に
//
> ''${変数名}''
<
とした方が,より安全だ.

&br;&br;
** String: 文字列 [#e01db0ec]

文字列は quotation で表す.
&br;
この時,
「&apos;」(シングルクォート)
で囲むのと,
「&quot;」(ダブルクォート)
で囲むのでは性質が異なるので注意が必要だ.  

: 「&apos;」(シングルクォート) で囲んだ文字列 |
何が書かれていても単なる文字列として扱う.
&br;&br;
: 「&quot;」(ダブルクォート) で囲んだ文字列 |
$ ` \ の3つの特殊文字をこれまで学んだ特殊な意味で扱う.
つまり,&quot;(ダブルクォート)で囲まれた文字列の中で変数の参照は行われる.
&quot;(ダブルクォート) の囲み内部で上の3つの特殊文字を単なる文字として扱いたければ,
\ を前につけて
\$ \` \\ とする.

&br;&br;
&ref(/materials/notes.png); 実習

先の Hello スクリプトを次のように改造しよう.

#highlighter(language=SH,number=on,cache=on){{
#!/bin/sh
# Greeting Script
g='Hello, world!'
d="today is `date +%m/%d`"
echo $g, $d.
}}

そして,何がどうなっているのか理解しよう.

&br;&br;
** Arguments: 引数 [#a884dc5c]

引数とは,プログラムを起動するときに,一緒に与える情報である.
例えば
''ls&#9251;-a&#9251;/tmp''
とプログラムを実行したら,(広い意味で)引数は ''-a, /tmp'' の二つである.
&br;
この引数は以下のように扱われる.

CENTER:■ sh 系シェルスクリプトでの引数の扱い ■

| 変数 | 意味 |h
| ''$#'' | 引数の個数 |
| ''$n'' | n 番目の引数.&br; ただし,0番目の引数 ''$0'' は特別で,シェルスクリプト自身の名前になる.&br;&br; また,n > 9 である場合は ''${12}'' などと,中カッコで囲まないと使えない. |
| ''$*'' | 引数全て.|
| (参考) ''$argv{m-n}'' | m 番目から n 番目までの引数の指定. ただし sh系では有効ではないようだ. bash などでは,引数の複雑な処理は ''getopts'' で行うのが良いだろう. |


*** Argument の操作: shift コマンド [#v7ea9031]
*** Argument の操作: shift コマンド [#pbf57d6a]

 ''shift'' というコマンドを実行すると,
''shift'' というコマンドを実行すると,
一つ目のオプションの内容が消去され,二つ目以降が前にずれる.
言い換えると,
$1 に $2 の内容が入り,
$2 に $3 の内容が入り… と
引数の内容が一つずつずれる.
結果として,オプションの数 $# は 1 減ることになる.
いった動作になる.
また,この結果としてオプションの数 $# は 1 減る.

&br;&br;
&ref(/materials/notes.png); 実習

Welcome というファイル名でスクリプトを次のように作る.

#highlighter(language=SH,number=on,cache=on){{
#!/bin/sh
# Welcome Script
name=`whoami`
g="($1 says) Thank you, $name"
echo $g.
}}

そして,このスクリプトを次のように実行してみよう.

> ''Welcome&#9251;Smith''

実行してみよ.
そして,スクリプトの内容を読んで理解せよ.

&br;&br;
** I/O: 入出力 [#j75b8d77]

シェルスクリプトが実行中に入出力を行うには,主に次のコマンドを用いる.

: ''read&#9251;変数'' |
入力.
&br;
ユーザからの(キーボード)入力を待ち,その結果を変数にいれる.
: ''echo&#9251;出力したいもの'' |
出力
: ''echo&#9251;-n&#9251;出力したいもの'' |
出力.ただし,出力後に改行しない.


&ref(/materials/Gnome-Preferences.png); 実行例.

#highlighter(language=SH,number=on,cache=on){{
#!/bin/sh 
echo -n 'Pls input something : '
read a
echo ' You input is ' $a
}}

を実行するとどうなるだろうか.

&br;&br;
&ref(/materials/notes.png); 実習

Hello スクリプトをさらに改造して次のようにしよう.

#highlighter(language=SH,number=on,cache=on){{
#!/bin/sh
# Greeting Script
g='Hello'
i='Please tell me your name: '
o="Oh, nice to meet you"
echo $g.
echo -n $i
read ans
echo $o, $ans.
}}

そして,このスクリプトを実行してみるとともに,何がどうなっているのか理解せよ.

&br;&br;
** Calculations: 計算 [#ne97e111]

オリジナル sh は計算機能をほとんど持っていない(bash は実は計算機能を持っている).
そこそこ新しい bash はともかく,
オリジナルの sh は計算機能をほとんど持っていない.
&br;
そこで,シェルスクリプト中で計算を行いたいときは,互換性も鑑みて,
そこで,シェルスクリプト中で計算を行いたいときは互換性を鑑みて
[[&ref(/materials/JNorth_arrow-right-sm.png); 便利!先読み評価 ``>授業資料/04#look-ahead-evaluation]]
を利用して外部コマンドを呼び出す.
を利用して外部コマンドを呼び出すなどの方法が採られることが多い.
&br;
具体的には,簡単な整数計算だけでよければ
''expr'' を,
やや複雑な実数計算を行いたければ
''bc''
などを使って次の例のようにする.

&ref(/materials/Gnome-Preferences.png); expr を使った例

#highlighter(language=SH,number=on,cache=on){{
#!/bin/sh  
a=5
b=`expr $a + 10` ; echo $b
c=`expr $b \* 2` ; echo $c 
}}

&ref(/materials/warning.png);
最後の行の ` ` の中で,* は展開されてファイル名などになってしまいかねないので,\* として(エスケープ),単なる文字としている.

&ref(/materials/notes.png); 実習

上のスクリプトを試してみよ.

&br;&br;
&ref(/materials/Gnome-Preferences.png); bc を使った例

bc は,標準入力から計算式をもらえる! ので,例えば ''echo'' で式を渡せば良い.
bc は,標準入力から計算式をもらって結果を標準出力に出せるので,例えば ''echo'' で式を渡せば良い.

#highlighter(language=SH,number=on,cache=on){{
#!/bin/sh  
a=`echo "4*a(1.0)" | bc -l` ; echo $a
b=`echo "c($a)" | bc -l` ; echo $b
}}

ちなみに,2行目で πを,3行目で cos(π) を計算している.

&ref(/materials/notes.png); 実習

上のスクリプトを試してみよ.

&br;&br;
** Functions of shell: シェルの関数 [#y62584d8]

sh 系シェルでは,関数を作れて,使える(要するに,コマンドをひとまとめにして名前をつけたもの).&br;
sh 系シェルでは,「複数のコマンドをまとめて名前をつけたもの」を自分で作って使える.
これはプログラミングの世界では ''関数'' とよばれる.
&br;

関数を作るには,

&br;&br;
''関数名 () {''
&br;      
&nbsp;
&nbsp;
''コマンド…''
&br;      
&nbsp;
&nbsp;
''}''
&br;&br;

という構文を利用する.
&br;
ちなみに,''{'' から ''}'' までの間で
関数に対する n 番目の引数を
''$n''
として参照できる.
&br;
&br;
また,この関数内部だけで使いたい変数があるときは,
''local''
を頭部につけて変数宣言をすればよい.

&br;
&ref(/materials/warning.png); SH の alias は変数をうまく使えないので,その代わりという意味でも積極的に使おう.
&ref(/materials/warning.png); 素の sh の alias は変数をうまく使えないので,その代替物として関数が役に立つ.

&br;&br;
&ref(/materials/Gnome-Preferences.png); 利用例.

#highlighter(language=SH,number=on,cache=on){{
#!/bin/sh

mawaru () {
  local i=1
  while [ $i -le 10 ]
    do
    echo $i
    i=`expr $i + 1`
    done
}

mawaru
}}

というシェルスクリプトはどういう動作をするか,考え,そして動かしてみよう.
なお,''while'' 文の意味と文法はこのすぐ後で学ぶ.
気になる人はそこを読んでから戻ってこよう.

&ref(/materials/notes.png); 実習

Hello スクリプトをさらに改造して次のようにしよう.

#highlighter(language=SH,number=on,cache=on){{
#!/bin/sh
# Greeting Script
g='Hello'
d=`date +%d`
dm=`expr $d - 1`
t=`date +%H`
m=`date +%M`

d2min () {
min=`echo "(($1 * 24) + $2) * 60 + $3" | bc -l`
}

d2min $dm $t $m
echo $g, "about $min minutes have passed this month."
}}

そして,このスクリプトを実行してみるとともに,何がどうなっているのか理解せよ.


&br;&br;
** Flow control of shell: シェルの制御構造 [#o62f3e62]

「もし…ならば」とか,「…を繰り返して…」という動作は次のようにする.

&br;&br;
*** Conditional branch: ''if'' … (単純)条件分岐 [#cb3e9697]

条件に応じて(二つに)分岐していく.
具体的な構文は以下の通り.

''if&#9251;条件1''
&br;
&nbsp;&nbsp;
''then&#9251;コマンド1 …''
&br;
&br;
&nbsp;&nbsp;
''elif&#9251;条件2''
&br;
&nbsp;&nbsp;&nbsp;&nbsp;
''then&#9251;コマンド2 …''
&br;
&nbsp;&nbsp;
''elif&#9251;条件3''
&br;
&nbsp;&nbsp;
&nbsp;&nbsp;
''then&#9251;コマンド3 …''
&br;
&br;
&nbsp;&nbsp;
''(以下, elif … then … を好きなだけ繰り返し)''
&br;
&br;
&nbsp;&nbsp;
''else&#9251;コマンドN …''
&br;
''fi''

&ref(/materials/warning.png); ''条件'' の書き方については,このすぐ後の 
[[&ref(/materials/JNorth_arrow-right-sm.png); 条件式および条件式のチェック>#condition-expression]] 
で学ぼう.

&ref(/materials/warning.png); ''elif'' 以下と ''else'' 以下は存在しなくても良い.

&br;&br;
上の構文での流れは以下の通り.

最初に 条件1 が実行 &amp; チェックされ,
&br;
条件1 が成り立つ(= 実行が成功する) → コマンド1… が実行されて if 文は終了する.
&br;
条件1 が成り立たない  → 次の elif へ.
&br;
&br;
→ 次の elif に来た場合.条件2 がチェックされ,
&br;
条件2 が成り立つ → コマンド2… が実行されて if 文は終了する.
&br;
条件2 が成り立たない  → 次の elif へ.
&br;
&br;
(… 以下,繰り返し …)
&br;
&br;
→ else に来た場合.無条件で コマンドN が実行されて if 文は終了する.

&br;&br;
&ref(/materials/notes.png); 実習

次のような内容のスクリプトを作り,実行し,理解せよ(ただし,''if'' のすぐ後の ''[&#9251;-e&#9251;$fn&#9251;]'' という部分については後述するので理解は後回しでよい).
次のような内容のスクリプトを作り,実行し,理解せよ.
ただし,''if'' のすぐ後の ''[&#9251;-e&#9251;$fn&#9251;]'' という部分については後述するので理解は後回しでよい.

#highlighter(language=SH,number=on,cache=on){{
#!/bin/sh

fn=~/.bashrc

if [ -e $fn ]
  then
    cat $fn
  else
    echo "You has no $fn."
fi
}}

&br;&br;
*** Pattern match: ''case'' … (パターンマッチ)条件分岐 [#a147f242]

ある「文字列」が用意したパターンとマッチするかどうかで分岐する.
単純な列挙の場合分けに便利.
パターンは "&brvbar;" で区切って並列表記(or を意味する)することもできる.

具体的な構は文以下の通り.
&br;&br;

''case&#9251;文字列&#9251;in''
&br;
&nbsp;
&nbsp;
''パターン1)&#9251;コマンド1… ;;''
&br;
&nbsp;
&nbsp;
''パターン2)&#9251;コマンド2… ;;''
&br;
&br;
''( 以下, パターンk)&#9251;コマンドk…;;  を好きなだけ繰り返し )''
&br;
&br;
&nbsp;
&nbsp;
''*)&#9251;コマンドN…''
&br;
''esac''

&br;
&br;
&ref(/materials/warning.png); *) は存在しなくても良い.


&br;&br;
流れは以下の通り.

&br;&br;
最初に 文字列 を評価して,
&br;
文字列がパターン1 とマッチする → コマンド1… が実行されて case 文は終了する.
&br;
マッチしない  → 次のパターンとマッチするか(以下繰り返し)
&br;
&br;
→ * ) に来た場合.無条件で コマンドN が実行されて case 文は終了する.

&br;
&br;
&ref(/materials/notes.png); 実習

&br;
&br;
次のような内容のスクリプトを作り,実行し,理解せよ.

#highlighter(language=SH,number=on,cache=on){{
#!/bin/sh

echo -n "Please input file name: "
read fn

case $fn in
  *.txt )
    echo "$fn is text file.";;
  *.c )
    echo "$fn is C program file.";;
  * )
    echo "Hey, what is $fn ? You know it?";;
esac
}}

&br;&br;
*** ''for'' … あてはまる変数の繰り返し [#o8e785d9]

具体的な構文と動作の流れは以下の通り.

&br;&br;
''for&#9251;変数&#9251;in&#9251;パターンorリスト''
&br;
''do''
&br;
&nbsp;
&nbsp;
''コマンド…''
&br;
''done''

&br;&br;
まず,パターンorリストを展開して,リストを生成する.
&br;
そのリストの要素を順番に 変数 に代入して,
そのたびにコマンド… を実行する.

&br;
&br;
&ref(/materials/notes.png); 実習

&br;
&br;
次のような内容のスクリプトを作り,実行し,理解せよ.

#highlighter(language=SH,number=on,cache=on){{
#!/bin/sh

for x in 0 1 2 3 4 5 6 7 8 9 10
do
  v=`echo "$x * 0.31416" | bc -l`
  echo "sin($v) = " `echo "s($v)" | bc -l`.
done
}}


&br;&br;
*** Loop: ''while, until'' … 条件チェックつきでの繰り返し. [#peaf97d4]

具体的な構文と動作の流れは以下の通り.

&br;&br;
''while&#9251;条件''
&br;
''do''
&br;
&nbsp;
&nbsp;
''コマンド…''
&br;
''done''

&br;&br;
&ref(/materials/warning.png); until の構文も同じ.

&br;&br;
まず,条件が成り立つかチェック.
&br;
[ while の場合] 成り立つならば,コマンド… を実行.
&br;
[ until の場合] 成り立たないならば,コマンド… を実行.
&br;
&br;
再び,条件が成り立つかチェック.
以下,繰り返し.

&br;
&br;
&ref(/materials/notes.png); 実習

&br;
&br;
次のような内容のスクリプトを作り,実行し,理解せよ(ただし,''while'' のすぐ後の ''[&#9251;$x&#9251;-le&#9251;10&#9251;]'' という部分については後述するので理解は後回しでよい).
次のような内容のスクリプトを作り,実行し,理解せよ.
ただし,''while'' のすぐ後の ''[&#9251;$x&#9251;-le&#9251;10&#9251;]'' という部分については後述するので理解は後回しでよい.

#highlighter(language=SH,number=on,cache=on){{
#!/bin/sh

x=0

while [ $x -le 10 ]
do
  v=`echo "$x * 0.31416" | bc -l`
  echo "sin($v) = " `echo "s($v)" | bc -l`.
  x=`expr $x + 1`
done
}}

&br;&br;
*** Break-out: ''break'' …ループ脱出. [#bed38841]

このコマンドが実行されると,for,while, until のループから脱出する.

&br;&br;
*** Termination: ''exit'' … 終了. [#l0afb597]

シェルスクリプトの終了.

&br;&br;
** Conditional statement: 条件式および条件式のチェック [#condition-expression]

sh 系シェルでは,条件は基本的に

> ''[&#9251;条件式&#9251;]''

という形式で書かれる.
&br;
&br;
&ref(/materials/warning.png); ''['' と条件式の間にはスペース&#9251;が必要!
&br;
# 詳しく言うと,[ は条件式をチェックする,という機能を持つコマンドである.
// 本来の名前は ''test'' である.
// どうなっているのかは,
// ''ls -lg `which [`'' などとしてみると分かるだろう.
&br;
&br;
条件式は,基本的に「単項演算子」か「二項演算子」と項目の組み合わせ.


*** statement for files: ファイルに関する条件式 [#r844cfa1]

: -e&#9251;名前 | その名前のファイルが存在するならば真.
: -d&#9251;名前 | その名前のディレクトリが存在するならば真.
: -f&#9251;名前 | その名前の通常ファイルが存在するならば真.
: -r&#9251;名前 | その名前の読み込み可能なファイルが存在するならば真.
: -w&#9251;名前 | その名前の書き込み可能なファイルが存在するならば真.
: -x&#9251;名前 | その名前の実行可能なファイルが存在するならば真.
: -s&#9251;名前 | その名前のサイズが 0 より大きなファイルが存在するならば真.

&ref(/materials/notes.png); 実習

制御構造 if のところの実習例などを参考にして,上の条件をなるべく全部試すスクリプトを作成してみよ.


*** statement for string: 文字列に関する条件式 [#u244d243]

: -z&#9251;文字列 | 文字列の長さがゼロならば真.
: -n&#9251;文字列 | 文字列の長さがゼロでなければ真.
: 文字列1&#9251;==&#9251;文字列2 | 文字列が等しければ真(見えにくいが,「=」が二つつながっている).
: 文字列1&#9251;!=&#9251;文字列2 | 文字列が異なれば真.


&ref(/materials/notes.png); 実習

制御構造 if のところの実習例などを参考にして,上の条件をなるべく全部試すスクリプトを作成してみよ.


*** statement for number: 数値に関する条件式 [#ydc517d6]

: 数値1&#9251;-eq&#9251;数値2 | 数値が等しければ真.
: 数値1&#9251;-ne&#9251;数値2 | 数値が異なれば真.
: 数値1&#9251;-gt&#9251;数値2 | 数値1 &gt; 数値2 ならば真.
: 数値1&#9251;-ge&#9251;数値2 | 数値1 ≧ 数値2 ならば真.
: 数値1&#9251;-lt&#9251;数値2 | 数値1 &lt; 数値2 ならば真.
: 数値1&#9251;-le&#9251;数値2 | 数値1 ≦ 数値2 ならば真.

&ref(/materials/warning.png); 条件式の判定には整数しか使えないぞ!


&ref(/materials/notes.png); 実習

制御構造 if のところの実習例などを参考にして,上の条件をなるべく全部試すスクリプトを作成してみよ.


*** other statement: その他 条件式 [#ce3657d8]


: !条件式 | ''NOT''を表す.
条件式が成り立たなければ真.
: 条件式1&#9251;-a&#9251;条件式2 | ''AND''を表す.
両方の条件式が成り立てば真.
: 条件式1&#9251;-o&#9251;条件式2 | ''OR''を表す.
どちらかの条件式が成り立てば真.
: ( 条件式 ) | 条件式をグループ化する.
複雑な条件式を書くときには,
意図と異なる結果にならないためにも積極的に使うべし.


&ref(/materials/notes.png); 実習

制御構造 if のところの実習例などを参考にして,上の条件をなるべく全部試すスクリプトを作成してみよ.



&br;&br;
* Report: レポート [#y5aab7ff]

以下の課題について能う限り賢明な調査と考察を行い,
&br; 
''AppliedMath7-Report-07''
&br;
という題名をつけて e-mail にて教官宛にレポートとして提出せよ. なお,レポートを e-mail の代わりに TeX で作成した書面にて提出してもよい.  

** Exercises: 課題 [#mdefa899]

+ 引数1 に「金額」を,引数2 に「日数」を入れると,
その金額でその日数だけお金を借りたら最終的にいくらになるかを計算するシェルスクリプトを作成せよ.
ただし,金利は 10日で 1割 (複利)とする.
&br;
&ref(/materials/warning.png);
ただし,
read コマンドなどを使わず,シェルスクリプトの引数をきちんと処理すること.
&br;
&br;
+ ファイルを消去するシェルスクリプトを作成せよ.
ただし,次の機能を持っているようにせよ.
++ ファイルのバックアップファイルがあるかどうか調べて,
--- 無い … 作成する.
--- その数が3つ以下 … 新たにバックアップファイルを作成する.
--- その数が3つより多い … 一番古いバックアップファイルを消去してから,
新たにバックアップファイルを作成する.
++ 以上の作業を行ってから,ファイルを消去する.
&br;
&br;
+ これまでの授業課題で,シェルスクリプトを利用して解決できる課題があればそれを行え.



&br;&br;
* about Icons, ClipArts [#vd8281c6]

For details, see [[&ref(/materials/JNorth_arrow-right-sm.png); this>materials]].

// ━┃┏┓┛┗┣┳┫┻╋


// コマンドライン入力は「行頭を > で始める」.
// コマンドライン出力は「行頭をブランクで始める」.

// 実習アイコン
// &ref(/materials/notes.png); 

// 注意アイコン
// &ref(/materials/warning.png);

// Link アイコン
// &ref(/materials/JNorth_arrow-right-sm.png);

// OK アイコン
// &ref(/materials/OK.png);

// NG アイコン
// &ref(/materials/NG.png);

// サンプルアイコン
// &ref(/materials/Gnome-Preferences.png);

// 大文字での強調 
// CENTER:&size(24){''ほげほげ''};

// programu source 表記
// #highlighter(language=ruby,number=on,cache=on){{}}

// パイプ
// &brvbar;

// 空白記号
// &#9251;