シェルスクリプト

【このページの内容は1996年ごろに書き、2002年ごろに部分改訂したもので、 それよりあとの世界の変化を反映していない。】

計算機を使って仕事をしていると、似たような操作をくりかえす ことが多い。計算機側での処理をくふうして、同じ文字列をキーボード からくりかえし入力する必要がないようにしたい、と考えるのは当然 の流れである。多くのOS (オペレーティングシステム)では、 ユーザーが記述した順序に従ってコマンドを実行する機能が用意されて おり、マクロコマンドなどと呼ばれることがある。MS-DOSではバッチと 呼ばれているが、ほかのOSではバッチ処理という用語は別の意味に使われ ていることもある。

Unixの場合、このようなコマンド実行手順を記述したものは 「シェルスクリプト」(shell script)と呼ばれる。 この名前は、Unixが、CPUの仕事の時分割やメモリーの割り付けなどを管理する カーネル(kernel, 核)と呼ばれる部分と、ユーザーからのコマンドを 受け付けるシェル(shell, 殻)という部分に分けられることから来ている。 シェルスクリプトとは、シェルに与えるコマンドを記述したテキスト ファイルなのである。シェルは一種のプログラム言語のインタプリタと みることができ、記述されたコマンドを順次処理することのほか、 条件分岐やくりかえしなどの制御構造をもったスクリプトを受け付けることができる。

Unixでは同じカーネルに対して複数のシェルをさしかえて使うことが できる。主なシェルとしては、Bell研究所時代からの歴史のある Bourne (ボーン) シェル「sh」と、カリフォルニア大学 バークレー校で作られたCシェル「csh」がある。 bashkshはBourneシェルを、 tcshはCシェルを、それぞれ発展させたもので、 基本的機能の範囲では同じとみてよい。 cshのほうが、会話型利用には適しているが、 シェルスクリプトに使うには文法が多少不便だったり 動作が不確実であった。 そのため、シェルスクリプトでは、今でもshが多く使われる。 しかし、最近ではcshも改良されてきたため、 会話型利用でcshを使っているユーザーには シェルスクリプトにもcshを使うことを勧めてもよいと 思う。

【ただし、システム管理者向けのシェルスクリプトは、 今もcshを使う傾向はない。 あいかわらずshを使うものも多く、 また新しく作られるものは、Perl言語のスクリプトが多いようである。 Perl言語はシェルではないが、system関数を使って Unixのコマンドを呼び出すことが簡単にでき、 一方、制御構造の表現はシェルより豊富である。】


シェルスクリプトの形

シェルスクリプトの基本形は、キーボードから入力する行に対応させて 改行で区切ってコマンドを書きならべたものである。

「#」という文字で始まる行はコメント扱いとなる。 ただし、シェルスクリプトの1行めの「#!」は特別な意味を持っている。

#!/bin/sh
と書いておけば、shが解釈して実行する。 cshで実行させるためには、
#!/bin/csh
と書いておけばよいのである(Unixであってもこの機能が組み こまれておらず、常にshで実行しようとするものもある かもしれない。)


ごく簡単な例

ここでは、条件分岐やくりかえしを扱わず、順次処理だけの例を とりあげる。この範囲では、shcshかの 違いはほとんど問題にならない。ただし、(以下の例にはないが) ファイル名を指定する際に~(波型、ティルデ)を使うこと など、会話型で使っている機能をそのまま使えたほうが便利なので、 cshを使った例を示す。

Pascal言語のプログラムtry.pを改訂しては実行する ことをくりかえしているとしよう。編集が終わると、try.p をコンパイルしてa.outを作り、実行し、いらなくなった a.outを消すという定型作業が簡単にできるようにしたい。 このとき、次のようなテキストファイルを、try.cshと いう名前で作っておくことにする。 【名前をcshで終わらせたのは人の覚えの ためであって、実行に必要なことではない。単にtryとしても よいが、もしtry.pをコンパイルした機械語プログラムにも tryという名前をつけてしまうと先に作ったほうが 消えてしまうので注意。】


#!/bin/csh pc try.p ./a.out rm a.out
これを実行するには、cshを陽(explicit)に呼び出して
% csh try.csh
としてもよいのだが、せっかく#!を書いたので、
% chmod +x try.csh
としてこのテキストファイルに「実行可能」属性をつけ(これは一度やって おけばファイルを消すまで有効)、
% ./try.csh
で実行する方法を知っておいたほうがよいだろう。


パラメタのある例

こんどは、ソースプログラムのファイル名がtry.pに限らず、 毎回変わるとしよう。 そして、コンパイルしてできた機械語プログラムには、 ソースプログラムに対応する名前(try.pに対しては try)をつけ、実行後も消さないで残しておくことにする。 また、実行の標準出力は、端末画面ではなく、 プログラム名のあとに.outをつけた名前のファイルに 入れることにする。 シェルスクリプトの名前はpcg.cshとしておこう。 このような場合、実行するには、ソースプログラムのファイル名の 幹の部分を

% ./pcg.csh try
のような形で キーボードから指定する方法が自然だろう。

シェルスクリプトを呼び出す場合、シェルスクリプトのファイル名の あとに文字列を書くことができる。これをパラメタ(parameter)または 引き数(argument)と呼ぶ。パラメタ間は原則として空白で区切られる。 シェルスクリプトの中では、

$1 は
1つめのパラメタ
$2 は
2つめのパラメタ (以下 $9 まで同様)
$* は
全部のパラメタを列挙したもの
を示す変数のように使うことができる。 【ただし、シェルには「ワイルドカードの展開」と 呼ばれる機能があり、 パラメタ中に*?を使うと、 それぞれ、任意の文字列、任意の1文字と解釈されて、 パラメタが条件に合うファイル名を列挙したもので置きかえられる。 こういった特殊文字を使った場合は、呼び出した側で記述した パラメタの個数と、シェルスクリプトに渡される個数とが一致しないことになる。】

したがって、pcg.cshの内容は次のように書けばよい。


#!/bin/csh pc -o $1 $1.p ./$1 >! $1.out
ただし、標準出力のリダイレクション(redirection)をあらわす >のあとに続く!記号は、出力先のファイルが すでに存在してもエラーとせず上書きしてしまうことを指示するものである。


参考文献

シェルスクリプトの書きかたは、多くのUnixの教科書で簡単に扱われているが、 特に詳しく書かれた参考書として次のものがある。 ただし、 shの系統ではbashcshの系統ではtcsh という、それぞれ改良が加えられたシェルを使う例が中心である。
ページ公開 2002年、微修正 2015-06-14
増田 耕一 (MASUDA Kooiti)

[目次へ]