■ はじめに
UNIXを使いこなすには、GUI(Graphical User Interface)でなく、CUI(Character User Interface)が必要です。
逆に云えば、コマンドを文字入力して、いかにUNIXに仕事をさせるのかが、UNIXを使いこなすと云うことです。
そして、文字入力したコマンドを解釈するものをシェルと云い、UNIXには沢山の種類のシェルがあります。
で今回、UNIXならどのOSでも必ずバンドルされているBシェル(sh)のスクリプトを勉強いたしましょう…ということです。
とにかく、Bシェルスクリプトです!その理由は、追って説明して参ります。
■ シェルとは
UNIXを一回でも使った人はおわかりと思いますが、ログインするとコマンドプロンプトがでます。
そして、ls等のコマンドを入力します。すると、コマンドが実行され結果が表示されます。
実は、ls等のコマンド名を解釈して実際のコマンドを呼び出し、実行させるものをシェルと云います。
また、複数のコマンドをテキストファイルに記述して、それをコマンドとして実行させることが出来ます。
このような、コマンド(テキストファイル)をシェルスクリプトと云います。
で実は、シェルスクリプトにもcsh,ksh,tcsh等いろいろありまして、結果的には、Bシェルスクリプト(sh)が一番なんです。
理由を挙げると以下の通りです。
- UNIXのシェルスクリプトとしては、一番普及しているのでなにかと有利。
- ファイルのリダイレクション機能が充実している。(Cシェルは、リダイレクションに関しては非常に貧弱)
- クォートが普通。(Cシェルは、クォートできないケースが多々存在する)
しかし、Bシェルだけでなく、Cシェルも仕事の都合でどうしても使わなくてはいけないこともあるでしょう。
ですので、補助的にCシェルも解説していきます。
Cシェルにも、BシェルにないCシェルなりのメリットがあります。配列操作、変数操作等やC言語に似た見た目などなど……。
まぁ、前書きはこのぐらいにして、では本文に参ります。
■目次:
- Bシェルスクリプトの書き方と実行方法について
簡単な例を使ってBシェルスクリプトの書き方と実行方法を解説します。 - コメントと改行について
スクリプト中のコメントの書き方とコード途中での改行方法について解説します。 - 変数について
変数への値の代入、変数の値の参照について解説します。 - 未設定変数の扱いについて
変数の中身が空の時や、変数そのものが未定義の時のいろいろな振る舞いついて解説します。 - 特殊な変数について
あらかじめ定義されている特別な意味を持つ変数について解説します。 - コマンド置換について
コマンドの実行結果を変数へ代入したり、プログラム中でどのように使うかについて解説します。 - エスケープシーケンスと文字列連結について
エスケープシーケンスと文字列連結について解説します。 - 四則演算について
数値計算等の四則演算を解説します。 - 制御文:ifとforについて
Bシェルの制御構文のうち、if、for文について解説します。 - 制御文:whileとcaseについて
Bシェルの制御構文のうち、while、case文について解説します。 - 条件の評価について
if文やwhile文で使用する条件判定について解説します。 - 関数の定義と使用について
独自に関数を定義して使用する方法について解説します。 - 入出力(リダイレクション)について
データストリームのリダイレクションについて解説します。 - 組み込みコマンドについて
test,eval,exce,trap等の組み込みコマンドについて解説します。 - BシェルスクリプトとCシェルスクリプトの相違点について
BシェルスクリプトとCシェルスクリプトの相違点ついて解説します。 - Bシェルスクリプトのデバックと注意点について
Bシェルスクリプトのデバックと注意点について解説します。 - 参考URL
本コンテンツを作成するにあたり、大変お世話になったページです。
ここに謹んで御礼申し上げます。
■本文:
◆ Bシェルスクリプトの書き方と実行方法について
以下のサンプルは、ごく簡単なBシェルスクリプトです。
viエディッタ等を使って以下の2行を書きこんだtest01.shファイルを用意してください。
ファイル名 : test01.sh
#!/usr/bin/sh echo これはBシェルスクリプトです。
1行目は、シバン(shebang)と云い、その後に続く部分をインタプリンタのパス名を指定します。ここでは「/usr/bin/sh」というプログラムを指定しています。しかし、システムによって違う場合もありますので、事前につぎのコマンドで確認することが出来ます。
$ which sh
Bシェルスクリプトとは、基本的には『テキストファイル内にUNIXコマンドを書き並べたもの』です。 2行目はこのスクリプトで実行されるコマンドです。
実行結果:
$ chmod u+x test01.sh $ test01.sh これはBシェルスクリプトです。
1行目のchmodコマンドでスクリプトファイルに実行権を与えています。これをしないと実行権限がないために、スクリプトの実行ができません。
2行目で実際にスクリプトを実行しています。システムによってはパス設定の関係で、./test1.sh」としなければならない場合もあります。
3行目が実行結果です。スクリプト2行目の『echo これはBシェルスクリプトです。』の実行結果が出力されました。
基本は、これだけです。しかし、この後に解説する制御文や変数のコマンド置換、引数渡し等を組み合わせると、非常に強力なツールになることを実感できるでしょう。
◆ コメントと改行について
普通、スクリプトのみでは分かり辛く、特に分かり難い所には、コメントを入れます。
Bシェルスクリプトでは、以下のスクリプトように、行の頭に「#」をつけることでシバン以外はコメントとすることができます。
ファイル名 : test012.sh
#!/usr/bin/sh # ここはコメントです。 echo "これはBスクリプト本体です。"
実行結果:
$ chmod u+x test02.sh $ test02.sh これはBスクリプト本体です。
スクリプト中の2行目は行頭に「#」がついているために、コメントとなり、実行結果に影響いたしません。
また、Bシェルスクリプトでは一行の文字数が長くなると、まぁ、見にくくなるものです。
そこで、適当に改行をするのがよいでしょう。
Bシェルスクリプトにおいて、行の途中で改行するには、以下のように改行する直前に「\」を入れて改行をエスケープします。
ファイル名 : test03.sh
#!/usr/bin/sh echo "これはBシェルスクリプトです。\ 改行をエスケープすると2行に記述できます。"
実行結果:
$ chmod u+x test03.sh $ test03.sh これはBシェルスクリプトです。改行をエスケープすると2行に記述できます。
◆ 変数について
変数名に使える文字は、英数字と「 _ 」(アンダーバー)のみで、一文字目に数字は使えません。
変数に値を代入するには「=」で変数名と値を結びます。「=」の左右に半角スペースを入れてはいけません。
また、変数の値を参照するには「$変数名」とします。
ファイル名 : test04.sh
#!/usr/bin/sh var="変数のテストです。" echo $var
実行結果:
$ chmod u+x test04.sh $ test04.sh 変数のテストです。
注意点:
『var="変数のテストです。"』の「=」の前後に半角スペース等を入れてはいけません。
空白、タブ、改行などを含んだ値を代入するには、値を引用符で囲みます。
var="変数のテストです。 スペースが入っています"
値の代入されていない変数は空文字となる。
varのみは、var=""と同じ。
変数参照時に変数が誤解釈されそうな場合には「""」または「{ }」で変数名を囲む。
var2={$var1}0
◆ 未設定変数の扱いについて
Bシェルスクリプトでは、変数の中身が空の時や、変数そのものが未定義の時に、いろいろな処理を行うことが可能です。
以下にその一覧を示します。
| 書式 | 変数が空でないとき | 変数が空のとき |
|---|---|---|
| ${変数 :-word } | 変数 の値が使われる | word の値が使われる |
| ${変数 :=word } | 変数 の値が使われる | word の値が変数に代入されて使われる |
| ${変数 :?word } | 変数 の値が使われる | word がエラーメッセージとして使われ、スクリプトが終了する |
| ${変数 :+word } | word が変数 に代入される | 何もしない |
| 書式 | 変数が定義されているとき | 変数が定義されていないとき |
|---|---|---|
| ${変数 -word } | 変数 の値が使われる | word の値が使われる |
| ${変数 =word } | 変数 の値が使われる | word の値が変数に代入されて使われる |
| ${変数 ?word } | 変数 の値が使われる | word がエラーメッセージとして使われ、スクリプトが終了する |
| ${変数 +word } | word が変数 に代入される | 何もしない |
・サンプル
ファイル名 : test17.sh
#!/usr/bin/sh
echo Are you name ? $who
echo Are you name ? ${who:-Chaichan}
echo $who
who=Macha
echo Are you name ? ${who:-Chaichan}
・実行結果は下のようになります。
$ chmod u+x test17.sh $ test17.sh Are you name ? Are you name ? Chaichan Are you name ? Macha
ファイル名 : test18.sh
#!/usr/bin/sh
echo Are you name ? $who
echo Are you name ? ${who:=Chaichan}
echo $who
who=Macha
echo Are you name ? ${who:=Chaichan}
・実行結果は下のようになります。
$ chmod u+x test18.sh $ test18.sh Are you name ? Are you name ? Chaichan Chaichan Are you name ? Macha
ファイル名 : test19.sh
#!/usr/bin/sh
who=Macha
echo Are you name ? $who
echo Are you name ? ${who:?"END Messege1"}
who=""
echo $who
echo Are you name ? ${who:?"END Messege2"}
・実行結果は下のようになります。
$ chmod u+x test19.sh $ test19.sh Are you name ? Macha Are you name ? Macha test19.sh: who: END Messege2
ファイル名 : test20.sh
#!/usr/bin/sh
echo Are you name ? $who
echo Are you name ? ${who:+Chaichan}
echo $who
who=Macha
echo Are you name ? ${who:+Chaichan}
・実行結果は下のようになります。
$ chmod u+x test20.sh $ test20.sh Are you name ? Are you name ? Are you name ? Chaichan
ファイル名 : test21.sh
#!/usr/bin/sh
who="Macha"
echo Are you name ? $who
echo Are you name ? ${who-Chaichan}
echo $who
echo Are you name ? ${who2-Chaichan}
・実行結果は下のようになります。
$ chmod u+x test21.sh $ test21.sh Are you name ? Macha Are you name ? Macha Macha Are you name ? Chaichan
ファイル名 : test22.sh
#!/usr/bin/sh
who="Macha"
echo Are you name ? $who
echo Are you name ? ${who=Chaichan}
echo $who
echo Are you name ? ${who2=Chaichan}
・実行結果は下のようになります。
$ chmod u+x test22.sh $ test22.sh Are you name ? Macha Are you name ? Macha Macha Are you name ? Chaichan
ファイル名 : test23.sh
#!/usr/bin/sh
who=Macha
echo Are you name ? $who
echo Are you name ? ${who?"END Messege1"}
echo $who1
echo Are you name ? ${who1?"END Messege2"}
・実行結果は下のようになります。
$ chmod u+x test23.sh $ test23.sh Are you name ? Macha Are you name ? Macha test23.sh: who1: END Messege2
ファイル名 : test24.sh
#!/usr/bin/sh
who="Macha"
echo Are you name ? $who
echo Are you name ? ${who+Chaichan}
echo $who
echo Are you name ? ${who2+Chaichan}
・実行結果は下のようになります。
$ chmod u+x test24.sh $ test24.sh Are you name ? Macha Are you name ? Chaichan Macha Are you name ?
◆ 特殊な変数について
Bシェルには、あらかじめ定義されている特別な意味を持つ変数があります。
以下は、主なそれの一覧です。
- $? :最後に実行したコマンドのexit値。
- $$ :シェル自身のプロセスID 。
- $! :シェルが最後に起動したバックグラウンドプロセスのプロセスID。
- $0 :スクリプトの名前。
- $1〜9 :スクリプトに渡された 何番目の引数 ($1は第1引数、…、$9は第9引数)
- $# :シェルに対する引数の個数(引数がない場合は0)
- $* :全引数リスト。ダブルクォートで囲んだ場合、"$1 $2 … $n" と展開される。
- $@ :全引数リスト。ダブルクォートで囲んだ場合、"$1" "$2" … "$n" と展開される。($*と$@の使い分けは微妙)
サンプルで確認してみましょう。
ファイル名 : test05.sh
#!/usr/bin/sh echo "引数の数は $# 個です。" echo "スクリプトの名前は $0 です。" echo "1番目の引数は $1 です。" echo "2番目の引数は $2 です。" echo "\$*の引数は $* です。" echo "\$@の引数は $@ です。" echo "プロセスIDは $$ です。"
実行結果は下のようになります。
$ chmod u+x test05.sh test05.sh aaa bbb 引数の数は 2 個です。 スクリプトの名前は test05.sh です。 1番目の引数は aaa です。 2番目の引数は bbb です。 $*の引数は aaa bbb です。 $@の引数は aaa bbb です。 プロセスIDは 15999 です。
◆ コマンド置換について
コマンドラインやシェルスクリプト中でコマンドをバッククォーテーション ( ` ) で囲むと、自動的にそのコマンドを実行した結果に置き換わります。
ファイル名 : test06.sh
#!/usr/bin/sh var=`date` echo $var echo "今日は `date` です。"
実行結果は以下のようになります。
$ chmod u+x test06.sh $ test06.sh 2004年06月03日 (木) 12時59分20秒 JST 今日は 2004年06月03日 (木) 12時59分20秒 JST です。
変数 var に date コマンドを実行した結果が代入されて、 date コマンドの出力結果が出力されます。
また、変数に代入しなくても、スクリプト中でバッククォーテーションで囲まれたものはコマンドとして解釈されます。
◆ エスケープシーケンスと文字列連結について
下に並べた文字は、シェルスクリプトでは特殊な文字として扱われ、そのままでは普通の文字として扱ってくれません。
; & ( ) | ^ < > ? * [ ] $ ` " ' { } [TAB] [SPACE]
これらを普通の文字として扱うためには、以下のように3通りのエスケープ方法があります。
バックスラッシュ( \ )により一文字エスケープ
バックスラッシュ ( \ ) の直後の特殊文字は普通の文字として扱われます。
シングルクォーテーション( ' )で囲む
シングルクォーテーション ( ' ) で囲まれた中の特殊文字はすべて普通の文字として扱われます。
ダブルクォーテーション( " )で囲む
ダブルクォーテーションで囲まれた中の特殊文字は $ ` \ を除いてすべて普通の文字として扱われます。つまり、ダブルクォーテーション中では 変数、コマンド置換 が行われます。これが、シングルとダブルのクォーテーションの意味の違いです。
サンプルスクリプト
ファイル名 : test08.sh
#!/usr/bin/sh var=hensunoatai echo $var echo "$var" echo '$var' echo '\$var'
実行結果は下のとおり。
$ chmod u+x test08.sh $ test08.sh hensunoatai hensunoatai $var \$var
・文字列の連結
シェルスクリプトで文字列を連結するには、単純に文字列同士を並べるだけです。
ファイル名 : test09.sh
#!/usr/bin/sh echo "おはよう!""さようなら…"
実行結果は以下のようになります。
$ chmod u+x test09.sh $ test09.sh おはよう!さようなら…
◆ 四則演算について
Bシェルスクリプトでは、変数は文字列として扱われ、数値として四則演算を行うには、expr というコマンドを使用します。
ファイル名 : test10.sh
#!/usr/bin/sh echo "8 + 2 = `expr 8 + 2`" echo "8 - 2 = `expr 8 - 2`" echo "8 * 2 = `expr 8 \* 2`" echo "8 / 2 = `expr 8 / 2`" echo "8 % 2 = `expr 8 % 2`"
実行結果は以下のようになります。
$ chmod u+x test10.sh $ test7.sh 8 + 2 = 10 8 - 2 = 6 8 * 2 = 16 8 / 2 = 4 8 % 2 = 0
exprコマンドの乗算の演算子は「*」ですが、シェルスクリプトが「*」を特殊文字として解釈するので「\」によりエスケープします。
◆制御文:ifとforについて
条件によって処理を分岐したい際に if文を使います。
if 条件; then コマンド ..... elif コマンド ..... else コマンド ..... fi
・if文に関するサンプル
ファイル名 : test11.sh
#!/usr/bin/sh if [ $1 = "argment" ]; then echo "引数はargmentです。" elif [ $1 = "hikisu" ]; then echo "引数はhikisuです。" else echo "引数は$1です。" fi
実行結果は以下のようになります。
$ chmod u+x test11.sh $ test11.sh argment 引数はargmentです。
リストに対しての繰り返しの処理にはfor文を使います。
for文 for 変数 in リスト do コマンド done
・サンプルを示します。
ファイル名 : test12.sh
#!/usr/bin/sh for var in x y z do echo $var done
実行結果は以下のようになります。
$ chmod u+x test12.sh $ test12.sh x y z
「リスト」は半角スペースか改行で区切ります。
変数が順に「リスト」の要素に置換され、do と done の間のコマンドが処理されています。
◆ 制御文:whileとcaseについて
繰り返しの処理には、while文を使います。
while文 while 条件 do コマンド done
条件が真である間 do done をループします。
・サンプルを示します。
ファイル名 : test13.sh
#!/usr/bin/sh a=2 while [ $a -lt 4 ] do echo "a = $a" a=`expr $a + 1` done
実行結果は以下のようになります。
$ chmod u+x test13.sh $ test13.sh a = 2 a = 3
複数の条件の時は、case文を使います。
case 変数 in パターン1) コマンド;; パターン2) コマンド;; パターン3) コマンド;; esac
変数が一致するパターンの後ろのコマンドが実行されます。パターンにはワイルドカードが使えます。
・ワイルドカード
| * | すべての文字列を表す。 |
|---|---|
| ? | 任意の1文字を表す。 |
| [...] | 鉤括弧内のどれか1文字を表す。 |
| [!...] | 鉤括弧内に含まれない文字を表す。 |
尚、Bシェルでのパターンは、正規表現でなく、あくまでもワイルドカードであることに注意して下さい。
サンプルを示します。
ファイル名 : test14.sh
#!/usr/bin/sh case $1 in X) echo "引数はXです。";; Y) echo "引数はYす。";; Z) echo "引数はZです。";; esac
実行結果は以下のようになります。
$ chmod u+x test14.sh $ test14.sh X 引数はXです。 $ test14.sh Z 引数はZです。
◆ 条件の評価について
if文やwhile文で使用する条件判定は、実は、testコマンドで実現されます。
testコマンドに関しては、『testコマンドの使い方』を参照して下さい。
・サンプル
ファイル名 : test15.sh
#!/usr/bin/sh if [ -n $1 ]; then echo "引数があります。" fi if [ $1 -gt 10 ]; then echo "10より大きい数の引数です。" fi
実行結果は以下のようになります。
$ chmod u+x test15.sh $ test15.sh 15 引数があります。 10より大きい数の引数です。
◆ 関数の定義と使用について
Bシェルスクリプトは、よく利用する複数のコマンド等を一つまとめに関数化することが出来ます。
・関数は以下のように定義します。
関数名() {
コマンド
.....
}
・サンプル
ファイル名 : test16.sh
#!/usr/bin/sh
func() {
echo "関数から表示。"
echo "関数の引数は $1 です。"
}
func arg1
実行結果は次のようになります。
$ chmod u+x test16.sh $ test11.sh 関数から表示。 関数の引数は $1 です。
・関数の使用(呼び出す)には
単純にスクリプト中で関数名をコールします。
また、関数に引数を渡すことができ、関数の中では、この引数を $1, $2, ... , $8, $9 で使うことができます。
◆ 入出力(リダイレクション)について
リダイレクションというのは,入力元や出力先を変更する機能です。
このリダイレクション機能を使うとファイルからコマンドにデータを入力したり,処理結果をファイルに書き出したりすることができます。以下のように『>』『<』を使って表現します。
| p1 | p2 | : p1の標準出力をp2の標準入力にする。尚、『|』は、リダイレクションでなくパイプと云う。 |
|---|---|
| >file | 標準出力をfileに書き出す。 |
| >>file | 標準出力をfileに追加書きする。 |
| >&m | 標準出力をファイルディスクリプタm番に向ける。 |
| >&- | 標準出力を閉じる。 |
| n>file | ファイルディスクリプタn番の出力をfileに書き出す。 |
| n>>file | ファイルディスクリプタn番の出力をfileに追加書きする。 |
| n>&m | ファイルディスクリプタn番の出力をファイルディスクリプタm番に向ける。 |
| n>&- | ファイルディスクリプタn番を閉じる。 |
| <file | fileから標準入力を読みこむ。 |
| <&m | ファイルディスクリプタm番からら標準入力を読みこむ。 |
| n<&m | ファイルディスクリプタm番の入力をファイルディスクリプタn番に向ける。 |
| <&- | 標準入力を閉じる。 |
| n<&- | ファイルディスクリプタn番を閉じる。 |
・サンプル
$ ls > /dev/null 2>&1
lsコマンドの標準出力をゴミ箱(/dev/null)に向け、つぎに標準エラーを標準出力向けています。
すると、結果的に標準エラーもゴミ箱へ向けたことになり、標準出力・標準エラーともにゴミ箱に行きます。
尚、標準出力のファイルディスクリプは『1』で、標準エラーのファイルディスクリプは『2』です。
ちなみに、標準入力は『0』です。
また、たとえば、上記を以下のようにした場合は、思わぬ結果になります。
$ ls 2>&1 > /dev/null
左から順に解釈されるので、まず、標準エラーが画面(標準出力)表示され、標準出力はゴミ箱へ行きます。
複雑なリダイレクトは以下を参照のこと。
http://www.netfort.gr.jp/~tomokuni/lms/shell/text/shell3.txt
・ヒヤ・ドキュメント
コマンドに複数行の文字列を標準入力させることができます。これをヒヤ・ドキュメントと云います。
command <<[-]word : ヒヤ・ドキュメント(メタキャラクタを展開する) command <<[-]'word' : ヒヤ・ドキュメント(メタキャラクタを展開しない)
尚、[-]の-を使用すると先頭からのタブが無視されます。
・サンプル
ファイル名 : test25.sh
#!/usr/bin/sh wknm=chaichan cat << END macha $wknm yasu END echo "-------------------" cat << 'END' macha $wknm yasu END
・実行結果は次のようになります。
$ chmod u+x test25.sh $ test25.sh macha chaichan yasu ------------------- macha $wknm yasu
◆ 組み込みコマンドについて
・testコマンドの使い方
testコマンドは以下のように使用します。
test 条件文
条件文は、文字列比較、数値比較、ファイルテストの3つのパターンがあります。
また、条件文は、testコマンドに引数となります。
条件文を引数として受け取ったtestコマンドは
条件が成り立つ(真)なら0、 条件が成り立たない(偽)なら0以外
という終了値を返します。
if文やwhile文の条件リストとして
if test "$HOME" = "/home/chaichan" ; then
のようにtestコマンドをそのまま使うと、少し見辛くなり、
そこで、"["と言うコマンドがtestコマンドのエイリアスとして用意されています。
これを使うと
if [ "$HOME" = "/home/chaichan" ] ; then
のように、見やすく記述することが出来きます。
ちなみに、『]』 というのは 『[コマンド』の引数で、
見た目を良くするためだけの意味のない引数になります。
・文字列比較
文字列の比較を行うには、以下の書式になります。
| -n s1 | 文字列s1の長さが0より大きいとき真。 |
|---|---|
| s1 | 文字列s1がNULLでないとき真。 |
| -z s1 | 文字列s1の長さが0のとき真。 |
| s1 = s2 | 2つの文字列が等しいとき真。 |
| s1 != s2 | 2つの文字列が等しくないとき真。 |
例えば、変数 NAME に入っている文字列が "chaichan"と等しいかどうかを
評価するには、以下のようにする。
test "$NAME" = "chaichan"
尚、第1引数は $NAME をダブルクォーテーションで囲みましょう。
これは、NAME が空っぽだったり未定義だった場合、
ダブルクォーテーションで囲まないと上記のコマンドは
test = "chaichan"
のように変数展開で第1引数が消えてしまい、エラーとなってしまいます。
従って、ダブルクォーテーションで囲む必要があるのです。
・数値比較
数値の比較を行うには、以下の書式になります。
| n1 -eq n2 | n1とn2が等しいとき真。 |
|---|---|
| n1 -ne n2 | n1とn2が等しくないとき真。 |
| n1 -gt n2 | n1 > n2 なら真。 |
| n1 -ge n2 | n1 ≧ n2 なら真。 |
| n1 -lt n2 | n1 < n2 なら真。 |
| n1 -le n2 | n1 ≦ n2 なら真。 |
| ! n1 | 論理演算NOT。 |
| n1 -a n2 | 論理演算AND。 |
| n1 -o n2 | 論理演算OR。 |
論理演算は、文字列比較、数値比較、ファイルテストの結果に対して
演算を実行できます。これを使えば、二つの変数 WK1 と WK2
を同時に評価する事ができます。
test "$WK1" = "chaichan" -a "$WK2" = "macha"
・ファイルテスト
ファイルの特性、パーミッション、ファイルサイズについて評価できます。以下の書式になります。
| -b ファイル | ファイルがブロック特殊ファイルのとき真。 |
|---|---|
| -c ファイル | ファイルがキャラクタ特殊ファイルのとき真。 |
| -d ファイル | ファイルがディレクトリのとき真。 |
| -f ファイル | ファイルがノーマルファイルのとき真。 |
| -r ファイル | ファイルが読み出し可能のとき真。 |
| -s ファイル | ファイルの長さが1バイト以上あるとき真。 |
| -w ファイル | ファイルが書き込み可能のとき真。 |
| -x ファイル | ファイルが実行可能のとき真。 |
たえば、${HOME}/chaichan というディレクトリが無かったら作成するという操作は、 以下のように行う。
if [ -d ${HOME}/chaichan ] ; then
mkdir ${HOME}/chaichan
fi
(現状testコマンドのみですが、eval,execコマンド等も解説する予定です)
◆ BシェルスクリプトとCシェルスクリプトの相違点について
私が解説するより、数段素晴らしいページがありますので、以下を参照して下さい。
- http://www.netfort.gr.jp/~tomokuni/lms/shell/text/shell4.txt
- http://www.klab.ee.utsunomiya-u.ac.jp/~hiroki/csh-whynot.euc
複雑なリダイレクトを使用しなければ、Cシェルスクリプトでもそこそこ使えると思うのですが……。
◆ Bシェルスクリプトのデバックと注意点について
Bシェルスクリプトのデバックですが、机上でよくチェックし、それでもわからない時は、echoコマンドでスナップショットをすれば、大体なんとかなります。
しかし、Bシェルには、予め xオプションでの実行時チェック機能があります。
また、、 nオプションでの構文チェック機能(スクリプトは実行されない)もあります。
たとえば、test13.shを実行時チェックをしてみると。
$ sh -x test13.sh a=2 + [ 2 -lt 4 ] + echo a = 2 a = 2 + expr 2 + 1 a=3 + [ 3 -lt 4 ] + echo a = 3 a = 3 + expr 3 + 1 a=4 + [ 4 -lt 4 ]
xオプションを使用すると、上記のように実行状態が表示される。
また、test13.sh内のdoneをxdoneにして構文チェックをしてみると。
$ sh -n test13.sh test13.sh: syntax error at line 8: `end of file' unexpected
nオプションを使用すると、上記のように構文チェックされ、しかし、スクリプトそのものは実行されない。
◆ 参考URL
本コンテンツを作成するにあたり、大変お世話になったサイトです。
ここに謹んで御礼申し上げます。
- http://www.rhythm-cafe.com/kb/shell/index.asp
- http://www.elect.chuo-u.ac.jp/tsuki/~tsun/lang/sh/index.html
- http://www.klab.ee.utsunomiya-u.ac.jp/~hiroki/csh-whynot.euc
- http://www.netfort.gr.jp/~tomokuni/lms/shell/text/shell.txt
- http://www.netfort.gr.jp/~tomokuni/lms/shell/text/shell2.txt
- http://www.netfort.gr.jp/~tomokuni/lms/shell/text/shell3.txt
- http://www.netfort.gr.jp/~tomokuni/lms/shell/text/shell4.txt