UNIX への招待 でのところを簡単にまとめておきましよう。 ・変数をとくに設定しないときは、省略時の値を設定して おく。 ・省略時の値を変更したいときは、プログラムの一部を変 ${option : =tl} さて、さきはどの例の、 示する。 変数が設定されていない場合は、エラーメッセージを表 を用いて変数を設定し直す。 更して変数の設定をし直すか、キーワード・パラメータ は、変数 option が設定されていないと、 . ${option : =tl} ラクタの置換えだけは実行します。したがって、 前述のように : は何もしないコマンドですが、メタキャ のところに丕しなければならないのでしようか。 場合に値 tl を代入するというこの作業は、なぜ : コマンド という行を考えてみましよう。 option が設定されていない : tl さて、こで : コマンドを使わすにコマンド行で、 に置き換えられ、 : コマンドはお役ご免になります。 やっておけばよいというときには : コマンドが便利なので このように、たんにメタキャラクタなどの置換えだけを として解釈されてしまいます。 ていない場合にこの行は tl に置き換えられ、 tl がコマンド だけを入力したとしましよう。すると、 option が設定され ${option: =tl} 156 えば、 C シェルでは、 という形式で、ある値を置き換えることができます。たと $ { 文字 } Bourne シェルでは、 自動的に定義される変数 す。 表 2 $ とともに使える文字 位置パラメータの数 最後に実行したコマンドからの終了ステータス このシ・エルのフ。ロセス識別子 実行時、または set で設定されたオフ。ンヨン 最後に六ックグラウンドで実行したコマンドの フ。ロセス識別子 位置パラメータすべて 位置パラメータすべて でそのシェルのプロセス識別子が置き換えられましたし、 では、そのシェルプログラムに対する引数の数が置き換え られます。同様に、 Bourne シェルでも、、文字〃の部分て特 定の文字を使うとある値が得られます。表 2 にその一覧を 記しておきます。 これまでにも、 $ # はさまざまな場面で使ってきました。 たとえは、 done などのように、引数の数を参照しながら実行を進めるとき に使います。 $ ? も、前回に登場しました。この方法を利用 すれば、シェルの子プロセスとして実行されたプロセスが その終了時にシェルに返した終了ステータスを参照するこ とができます。 $ $ は、 C シェルの説明のところで登場しました。 C シェ ルと Bourne シェルに共通で、 ( そのシェルのシェルプロ グラムであれば ) そのプログラムを実行しているシェルの プロセス識別子に置き換えられます。これは、一時ファイ ルを作るような場合によく利用します ( 詳細は 1990 年 11 月号の 155 べージを参照してください ) 。 $ ! には、最後にバックグラウンドで起動したコマンドの プロセス識別子が置き換えられます。これは、シェルプロ グラムではなく、対話形式での Bourne シェルで使うとけ っこう便利です。 Bourne シェルには、ジョブ制御の機能が ありません。したがって、バックグラウンドで実行したプ while test $ # —ne 0 echO $ 1 shift UNIX MAGAZINE 1991.1
e & 0 ce の属性をデータベース化して保存、これに よってバックアップ情報を参照できる。 価格は、 Standard Package(Sun 用の ent Package が 150 , 000 円。販売予定は、 サーバーとクライアント ) が 150 万円、 Cli- 初年度 1 , 800 セット。 用でき、デバッガの利用によりエラーの発 生場所を容易に検出できる。 オプションのデータベース・コネクショ AASSIST ンを利用すれは、メニュー選択あるいは アシスト (Tel 044 ー 951 ー 5678 ) は、統合 ァイルを介したデータ転送により、 MS- SQL 文の入力により外部データベース 表計算ソフト「アシストカルク」 UNIX 対 DOS 版とデータの圧換性が保てる。 (Oracle 、 Sybase など ) からデータを検 応版の販売を開始した。 UNIX 版はメモリ制限がないことから、 索、ワークシートのデータとして展開可育 米 Access TechnoIogy の、、 20 / 20 〃を 計算速度が向している。対応機種は 価格は 87 , 300 円から。データベース・コ 日本語化したもので、 UN Ⅸ版と販売中の Sun, NEWS など。 Sun 版ではメニュー選 ネクションとのセット価格は 137 , 000 円。 MS-DOS 版の操作はほは、同しマクロフ 択、セル移動、範囲指定などにマウスが使 販売予定は、年間 10 , 000 本。 DECstation 版 Common Lisp IJN Ⅸ対応統合表計算ソフト ÄDSS ダイヤセミコンシステムズ ( TeI 03 ー 487 万円。 ー 4351 ) は、米 Franz 社の DECsystem 用 ◆ AIIegro Common Windows 「 AllegroCL 」、 CL のウインドウ対応ソフ Lisp で GUI を作成するためのウイン トウェア「 AIIegro Common Win- ドウ・ツールキット。 IntelliCorp の Com- dow 」、ウインドウべース開発環境「 Alle- mon Windows をベースに、 DEC Win- gro Composer 」の販売を開始した。 dow ( X11 ) に対するアクセスが可能。 ドウべース・プログラム開発環境 オプジェクト指向により、 Reshape 、 ウインドウ化されたインスペクタやデバ ◆ Allegro CL ッガ、グラフ表示のプロファイラなどの機 "Common Lisp : The Language ”で Repaint 、 Shrink 、 Move などのウインド 規定された機能を実現した Common ウ管理方法を使用したアプリケーション・ 能があり、実行速度を最適化する統計分析 Lispo インタープリタ、コンパイラ、ファ プログラムを容易に開発できる。グラフィ ツールもサポートしている。 ンクションのセットから構成される。 ックス操作には CIRCLES 、 RECTAN- 実行中のプロセスや変数、フレーム、局 Flavors 、オプジェクト指向などの機能 所変数などの表示は、インスペクタやデバ GLES 、 TRIANGLES 、 POINTS 、 を拡張。コンパイル時にデバックと実行速 LINES などの関数を色指定っきでサポー ッガ、プロファイラ、バラメータのウイン 度のトレードオフが可育 foreign-func- トする。 ドウとともにマルチ・ウインドウ形式で表 価格は、 DECstation 2100 / 3100 、 DEC- tion interface 機能やスタックグループに 示される。 system 3100 / 5000 / 5400 / 5810 の場合が よる多重処理をサポート。 価格は、 DECstation 2100 / 3100 、 DEC- 125 , 000 円。 DECsystem 5820 / 5840 の場 価格は、 DECstation 2100 / 3100 、 DEC- system 3100 の場合が 250 , 000 円。 DEC- 合が 250 , 000 円。 system 5000 / 5400 / 5810 / 5820 / 5840 の system 3100 の場合が 750 , 000 円。 DEC- system 5000 / 5400 / 5810 の場合が 150 万 ◆ AI 1 egro Composer 場合が 500 , 000 円。 会話形式の Common Lisp 用のウイン 円、 DECsystem 5820 / 5840 の場合が 225 MIPS システムのソースコード 連ソースコードのライセンス再販売につい ターフェイスなどの改良・機能追加などの をライセンス て同社と契約を締結した。 作業に着手している。 日本電気の R3000 の量産の具体イヒにと 価格は、 OS 、コンパイラが 1 , 800 万円 SRA もなう、組込みューサーなどを対象とした にれとは別に、 AT & T のライセンス取得 SRA(Tel 03 ー 234 ー 2621 ) は、米 Mips もの。今回の契約により同社でのカスタマ が必要 ) 。 Computer Systems 社の OS 、コンノヾイ イズが可能になり、すでにユーサー・イン ラ、 R3000 用開発ツールなどのシステム関 3 UNIX MAGAZINE 1991.1
UNIX への招待⑩ default : set filename=$argv [ 1 ] 15 16 17 18 shift 19 end できます。ただし、 % samp -a または % samp -b endsw このプログラムには、オプションとして一 a やー b が指定 % ls —lt UNIX のコマンドのなかには、 ls のように と指定することはできません。 % samp -ab という形式は可能ですが、 UNIX MAGAZINE 1991.1 $ cat sample のなかにはマイナス記号で始まっている文字列がたくさん ーークが必要です。なぜなら、 get 叩 t で取り出される引数 入されます。このとき、 Bourne シェルの set コマンドには argv に、 Bourne シェルの場合は位置パラメータ変数に代 れた getopt コマンドの実行結果が C シェルの場合は変数 となります。いすれの形式でも、バッククオート (') に挟ま set getopt オプション文字列 $ * ( Bourne シェノレの場合 set argv ('getopt オプション文字列 $ * ( ) C シェルの場合 使い方は、 個々のオプションを取り出すという機能をもっています。 getopt は、シェルプログラムに対して指定された引数から ンを ls と同しような形式で指定するためのコマンドです。 getopt コマンドは、シェルプログラムに対するオプショ と別個に指定してもかまわないものがあります。 % ls ー 1 —t 定しても、 とオプションを 1 つのマイナス記号の後ろで連続して指 あると考えられるからです。前述したように、 Bourne シェ ルの set コマンドは、引数のなかにマイナス記号が先頭に ついた文字列を検出すると自分に対するオプションが指定 されたと判断してしまいます。このようなときは、 set の第 1 引数に一一を指定するのでしたよね ? getopt の最初の引数は、、、オプション文字列〃となってい ます。ここでは、このシェルに対してどのようなオプショ ンが使用できるかを列挙しておきます。たとえば、 getopt abc であれば、シェルに対するオプションとして、 の 3 つが指定できることになります。オプションによって は、それ自身に対する引数をとることもあります。 tar cvf /dev/rstO こでは、 f オプションに対する引数が /dev/rst0 です。 これと同しように、 getopt ではオプションがさらに引数を とるかどうかも指定できます。この場合は、オプション名 の後ろにコロン ( : ) を付けます。たとえば、 getopt cvf : とすると、、、オプション一 c 、 -v 、一 f が指定可能で、一 f はさ らに引数をとる〃という意味になります。 getopt の最後の引数では、 getopt がオプションを取り 出す文字列ーー - すなわちシェルプログラム実行時に指定し たすべての引数を指定しておきます。これは、 C シェルで も Bourne シェルでも $ * とするだけでかまいません。 それでは、 Bourne シェルプログラムで getopt を使っ た例を見てみましよう。 159
UN Ⅸへの招彳⑩ と、シグナルを受けた際にそれを無見します。 3 番目以降 の引数では、具体的なシグナルの番号を指定します。 で 0 を指定すると、シェルプログラム終了時に処理が実行 されます。また、複数のシグナル番号を指定する場合は、 それぞれをカンマ ( , ) で区切ります。ここで使用できるシ グナルの番号とその意味は UNIX のバージョンごとに若 / trap "echo warikomida! ; 斑ー /tmp/$$ ; exit 1 " 9 trap $ cat sample もう 1 つ例を見てみます。 と記憶します。 の 3 つのコマンドを実行する。 exit rm /tmp/$$ echo worikomida ! シグナル 9 番が送られたときは、 シェルはこの trap コマンドを読み込んだ後、 、ゝ干の違いがありますので、自分が使っているシステムの kill や signal などのマニュアルを参照してください。 こで、次のような trap コマンドを考えてみましよう。 trap "ech0 矼 ikoml ; 2 3 , 9 これは、シグナル 9 番が送られた場合の処理をしてい ます。 す。 けたくない場合、 trap を用いれは簡単にそれが実現できま のある部分を実行しているときだけ強制終了などを受け付 は echo と exit が実行されます。このように、プログラム と、今度はシグナル 2 、 3 、 9 のいすれかが送られたとき 行か継続されます。そして、 2 番目の trap が読み込まれる おこなわれす、そのシグナルは無視されてプログラムの実 れた後、シグナル 2 、 3 、 9 のいすれかが送られても何も このプログラムでは、最初の trap コマンドが読み込ま シェルプログラムへのオプション こでは、 SystemV でシェルプログラム用に提供され ている getopt というコマンドを紹介しましよう。 すでに何度も説明しましたが、シェルプログラム実行時 にはプログラムに対する引数が指定できます。指定した引 数は、 C シェルの場合はシェル変数 argv に、 Bourne シェ 3 while ( $#argv > 0 ) 2 set Usage="$O 1 # ! /bin/csh % cat samp ルの場合は位置パラメータ変数に代入されます。 シェルプログラムの引数としてオプションを指定する場 合を考えてみましよう。 次の例は、 1990 年 10 月号で C シェルの switch コマン ドについて説明したときのものです。 ト司 C-b] Cfi1ename] " ( $ 矼空 [ 1 ] ) 4 5 6 7 8 9 10 11 12 13 14 158 swit ch case case set optiona breaksw set optionb breaksw echo " $ 0 : illegal option ー exit echo "$Usage't $ 矼空 [ 1 ] " UNIX MAGAZINE 1991.1
連載 /IJN Ⅸ Communication Notes—の ない、実装されていない、あるいは不要なコマンドで 小分類 x5z ファイルシステムに関連したもの。 x4z その他。 x3z ューサー認証に関連したもの。 ョンに関連したもの。 x2z コントロール・コネクションまたはデータ・コネクシ を要求するコマンドへの返答。 xlz 状態問合せへの返答やヘルプメッセージなど、情報 あるというエラー ーバーの OS が UNIX などの場合には課金名がない ( ロ していることがあります。これは、それへの対応です。サ では、ユーサー名と計算機の使用量の請求先の指定が独立 課金“ c 厩を指定します。メインフレームなどの OS ACCT co ″厩 コマンドの直後に送られなければなりません。 パスワードが必要な場合には、 PASS コマンドは USER パスワードとしてカ s 0 を指定します。アクセスに PASS カ s 0 なります。 ドを送ると、すでに送ったパスワードの課金指定は無効に しサーバーをアクセスすることが可能です。 USER コマン 回でも発行できますから、改めて別のユーサーの権限で同 スワード、課金の 3 つでおこないます。このコマンドは何 を指定します。 FTP では、利用者の認証はユーサー名、パ ューサー名 ( UNIX の場合はログインネーム ) に襯 e USER 襯召 アクセス・コントロール関係のコマンド で書かれているのが引数です。 て SERVER-FTP がおこなう動作を説明します。小文字 ンドだけです。以下に FTP のコマンドと引数、それに対し RFC959 に規定されたなかでインプリメントされたコマ リスト 1 の HELP コマンドに対して返ってきたのは、 FTP のコマンド る規定はなく、コマンドごとに定義されています。 リプライコードの 3 桁目には全体をとおした一貫性のあ 40 グイン名がユーサー名と課金番号の両方を意味する ) ので、 課金指定は省略されます。 前節で説明したカテゴリー 3 のリプライコードの代表的 な使用例は、ログイン・シーケンスです。 PASS コマンド に対して、ログインが完了したら 230 が返ってきます。 スワードが誤っていると、エラーで 532 が返ってきます。 パスワードはあっているが、課金指定が必要な場合は 332 がリプライコードになります。 USER-PI は、これによっ てユーサーにアカウントの入力を督促するか否かを切り替 えます。 CWD カ 4 ル 4 襯 e Change Working Directory ーーーワーキング・ディレ クトリの変更です。 UNIX のようなディレクトリをもつ単 ーの階層的ファイルシステムでは、加襯はディレク トリへのパス指定です。これは、通常のシェルの cd コマン ドと同しです。 Macintosh や MS-DOS 、 VMS のような 複数ポリューム ( ドライプ ) からなる階層的ファイルシス テムではポリューム指定が必要です。たとえば Macintosh の NCSA-TELNET に組み込まれている FTP サーバーでは、ポリューム名がルートディレクトリ 直下のディレクトリ名であるかのごとくみえるように実装 されています。そして、フォルダーはディレクトリにみえ ます。 HD40 というディスクポリュームのフォルダー sys - tem のなかのフォルダー SP001 に移るには、 CWD /HD40/system/sp001 というコマンドを送ります。 ディレクトリをもたない OS でも、ファイルのグループ を指定するなんらかの機能がある場合には、そのファイル グループ指定を CWD コマンドでおこないます。 CDUP 親ディレクトリにワーキング・ディレクトリを移します。 サーバーが UNIX の場合には、 と同しですが、親ディレクトリを指定する方法は OS によ って異なるので FTP コマンドとして採用されました。 SMNT 加〃 4 川 e (Structure MouNT) UNIX MAGAZINE 1991.1
話がまた横道に逸れてしまいましたが、要するに、ある コマンドの出力に処理を施したい場合にはその出力をファ イルに格納しておき、それに対してもう 1 度処理をおこな えはいいのです。でも、この方法では途中で作成した中間 ファイルをあとで消去しなければなりません。何回も使用 するようなファイルならいいのですが、プリントアウトだ けを目的に作成したファイルはすぐに用すみになります。 UNIX には、こんなふうに中間ファイルを使わなくても簡 単に実現できる方法が存在します。それが今回お話しする パイプです。 パイプとは複数のコマンドのあいだをつなぐ文字どおり のヾパイプ〃役ですが、前のコマンドの標準出力を次のコ マンドの標準入力につないでくれます。ものは試し、実際 にやってみましよう。さきほどの例と同様に、カレントデ ィレクトリの一覧をプリンタから出力するには次のように します。 % ls ー lpr ほら、簡単でしよ。パイプについて理解するのは、これ までお話ししてきた標準入出力が分かっていれはそれはど 難しくはありません。縦棒ソ〃で示されているのがパイ プです。縦棒の左側のコマンド (ls) の標準出力が、右側のコ マンド ( lpr ) の標準入力となっているのです。このようにし て使うパイプは、いくつでもつなげることができます。た とえは、 1 行に 1 つの単語が書いてあるファイル中の単語 数を使用頻度順に表示したけれは、 sort ファイル名ー uniq —c ー sort —nr とすれは得られます。また、コマンドの出力結果が長くな りすぎて 1 画面に収まりきらない場合にもこのパイプの機 能がよく用いられます。コマンドの出力をファイルに格納 しておいてゆっくり見直してもいいのですが、ちょっとだ け見たい場合などはそれも面倒です。そこで登場するのか more コマンドなどのページャコマンドです。たとえば、あ るディレクトリに存在するファイルの一覧を見たいのだが、 ファイルの数が多すぎて上のほうが消えてしまうようなと き、あなたならどうしますか ? 私なら、 % ls —C ー more として、しつくり見られるようにします。 UNIX MAGAZINE 1991.1 IJN Ⅸ流プログラミング 3 more は有名なコマンドですからご存しの方も多いでし ようが、基本的にはファイルの中身を見るためのものです。 長いファイルを見る際に cat コマンドを使ったのでは、 S と Q を使って出力を一時的に止めながら見ていかないと すぐに画面からはみ出してしまいます。しかし、 % more ファイル名 とすれは、 1 画面ぶん出力した段階で出力がいったん停止 して画面の下のほうに、、一一 More ー〃と表示され、ユーサー からの入力待ちの状態になります。そこでリターンキーを 入力すると次の 1 行が、スペースを入力すると次の 1 画面 が表示されます。なかには、この段階で b キーを入力する と 1 画面ぶん前に戻るものもあります。 more は、このようにして長いファイルを見るために使 います。しかし、ファイル名を指定せすに実行し、かっそ の more コマンドがバイプの後ろのコマンドである場合、 パイプの前のコマンドの出力に対してさきほどの操作をお こなえるようになります。これからは、パイプの最後のコ マンドとしてこの more を指定することも増えるでしょ つ 2 前回、標準ェラー出力をファイルにリダイレクトする方 法についてお話ししました。これと同様に、標準ェラー出 力を標準出力と一緒にパイプに流す方法があります。、、せっ かく別に出力したエラー出力をわざわざ一緒にして何が面 白いんだ〃などという声も聞こえてきそうですが、これは これで意味があるのです。 たとえば、あるプログラムのコンパイルがうまくいかな かった場合を考えてみましよう。 C 言語などでプログラム を書いているとよく起こりますが、 1 つの誤りが連鎖的に 多数の誤りを生しさせることがあります。しかし、コンパ イルエラーを示すメッセージは画面のはるか上方に消えて しまい、画面上に残っているのは最後のほうの意味のない メッセージだけになってしまったりします。このような場 合には、標準ェラー出力もまとめてパイプに通し、 more な どを用いてしつくり眺めれは・よいのです。 (csh の場合 ) % CC maln. C ー & more $ cc maxn. c 2 > & 1 ー more ( sh の場合 ) とすると、標準ェラー出力もパイプに流してくれます。指 2 more の機能を拡張した、前に戻れるフリー・ソフトウェアの less というコマン ドも存在します。 131
連載 ZAn lntroduction to X Window system で設定内容の収められたファイルを指定します。 鍵ファイルのロック % xauth remove kochira: 0 使います。 登録された内容を削除するときは、 認証項目の削除 コメント行として無視されます。 バッチファイルでは、 sh と同様に、、 # 〃から始まる行は remove コ ~ ンドを 異常終了でロックがかかりっ放しになったときには、、、一 b 〃 ションで強行突破することもできます。また、なんらかの を参照したいときや強制的に変更したい場合は、、、イオプ クがかけられて読み書きが禁止されます。どうしても内容 どこかで xauth が実行されていると、ファイルにはロッ ます。 トされている場合も安心して xauth コマンドが利用でき がって、 NFS などで自分のホームディレクトリがマウン あるので、ロックがかけられるようになっています。した 鍵ファイルはネットワーク上で同時に利用されることも クライアントの設定 オプションで逃けられます。 UNIX MAGAZINE 1991.1 うになります。 xhost の登録の有無にかかわらすサーバーが利用できるよ ' の訒証データとサーバーのもつ認証データが合致すれば、 ルに乗せて鍵データをそのなかに送り、認証を求めます。 目を見つけだします。そして、指定される暗号化プロトコ のなかから接続しようとしているサーバーに合致する項 ウインドウの利用開始に際しては、ますこの鍵ファイル なったおかげです。 イルを扱うライプラリが R4 から Xlib に含まれるように ファイルとして使われます。これは、認証のための鍵ファ には各ューザーのホームディレクトリの . Xauthority が鍵 いればその変数の指すファイルが、設定されていない場合 xauth と同様に、環境変数 XAUTH 〇 RITY が設定されて クライアントの設定は、鍵ファイルを用意するだけです。 サーパーの設疋 一方、利用の認証をおこなう側のサーバーにも鍵ファイ ルが必要です。サーバー側では、オプション指定によって 鍵ファイルを指示するとともに認証のためのプロトコル が選択されます。このオプションは、、 -auth 鍵ファイル〃 ですが、ます xinit で X を起動して利用する場合から説明 しましよう。 xinit での鍵ファイルの利用 xinit の場合は、 % xinit —auth 鍵ファイル です。一般的な . Xauthority ファイルを用いるときは、 % xinit —auth ~ /. Xauthority となりますし、環境変数 XAUTH 〇 RITY が設定されてい れば、 % xinit -auth $XAÜIYORITY として X を起動します。 毎回、間違わないようにオプションを指定するのも面倒 ですから、 startx などの名前をつけたシェルプログラムに 組み込んで利用するほうが便利でしよう。 一般に、セッションとしてのクライアント (xterm など ) は X のサーバーが立ち上がった直後に unix ドメインに (unix:0.0 などによって ) 接続されます。クライアントとサ ーバーの双方に、指定される鍵ファイルにサーバー実行の ホスト名の付いた unix ドメイン ( たとえば、ホスト名 $kochira" に対しては、、 kochira/unix:0" の項目 ) が用意 されていなければ、いつまでたっても X を利用することは できません。 ネットワークを利用して多数のコンピュータ上でクライ アントを実行する際は、あらかしめ鍵ファイルをそれぞれ のコンピュータに配っておきます。複数のサーバーを利用 するときの登録には、それぞれのサーバー実行環境から対 応するサーバーの項目だけを抜き出してクライアント側の ファイルに加えるため、 145
図 2 f00 resume ( f00 ) bar re sume ( bar ) こくて、味がありますしね : ー ) ) 。 setjmp ( ) 、 longjmp ( ) はできるようですから、次はいよ いよコルーチンです ( リスト 1 参照 ) 。 f00 も bar も無限ループを回って文字を打ち続けるだ けですが、ループの最後で call-with-current-continua- tion をやっています。これにより、自分が眠ると同時に今 から起きるコルーチンを指定するわけです。もっともこの 例では 2 つしかコルーチンがいないので、自分が寝るとき にはかならす自分でないほうの人を起こすということにな っています ( はとんどこのままで、もっとたくさんのコルー チンを動かすことができます ) 。 f00 と bar がまったく同し形でないのは、 Scheme でコ ルーチンを作る場合は最初に 1 度だけどこかを関数呼出し で呼はないと仕事が始まらないからです。そのため、 では f00 を最初のスタートアップの関数にすることにし て、 f00 から仕事を始めるようにしたのです。 bar は f00 の コンティニュエーションを引数でもらうため、初期化の必 要がなくなり簡単になっています。 f00 の 2 行目の let は、ローカル変数 other-process の 場所を確保しながら bar を (call-with-current-contin- uationbar) で呼び出して起動します obar がループを 1 回 だけ回った後 f00 を resume したときには、 bar のコンテ イニュエーションがさきほどの (call-with-current-con- tinuation bar) の戻り値として渡され、 f00 のなかの変数 other-process にセットされるわけです。それから f00 は ループに入り、あとは bar と同様にループを 1 回まわるた びに最後の call-with-current-continuation で bar を resume して、自分は CPU を明け渡します ( 図 2 参照 ) 。 こういうふうにやってみて Scheme の言語仕様がよく できていると思うところは、 call-with-current-continu- ation が自動的につける引数がコンティニュエーションを 評価したときの戻り値としてうまく渡せることによって、 コルーチンがたいへん作りやすくなっている点です。この 102 仕様により、自分は寝ながら誰かを起こすということがし つに都合よくできるようになっています。 スケジューラなしで動く さて、これでスケジューラなしでみんなが対等というコ ルーチンが作れました。 OS やランタイム・ルーチンがいっ さいなくても、これほどマルチプロセスらしい感覚が味わ えることについてどう思われるでしようか ? 仕の例はマ ルチプロセスというには貧弱すぎますが、容易に複雑なも のに拡張できるでしよう ) 。 親があれば結局はそれがスケジューラになるので動くの は当り前ですが、スケジューラもないのにプロセスがうま い具合に連係して動くというのは、 CPU パワーもメモリ も極小だった時代には大きな意味があったのではないでし ようか ? しかし、それにしてもコルーチンは何に使えはいいので しよう ? 『構造化プログラミング』ではテキスト変換器の たぐいが示され、「プロセスと同期 19 回一 CSP 」から参照さ れている文献 " D お〃 S ゆ〃房 e 乃 ans ″あれ Dia- g 川川 CO が / げ " [ 10 ] ではなんと COBOL コンパイラに 応用してありました ( 時代だなあ、僕まだ 3 歳だったぞ ) 。 この 2 つは、 UNIX なら複数のプロセスに分けてパイプで つないでやるような仕事をコルーチンを使って解決してい るわけです。大昔に OS なしでこんなことをするなんて、 感動的ですね。 また、『構造化プログラミング』では機械どうしにゲーム をさせるという話もでています。『コルーチンとは』 [ 3 ] で は、プロセスというよりは実行の履歴を保存しておくため に使用して、バックトラッキングを実現するための道具と して紹介しています。しかし、バックトラックというのは まずかったものは捨ててしまうので、せつかくコルーチン を使うなら昔 AI で流行ったフレームを実現したほうがう UNIX MAGAZINE 1991.1
ントアウトには lpr コマンドを用います。 こでは、次のよ うにしてみましよう。 % ls cat . c cat . sh catl . c cat2. c cat3. c cat4. c cat5. c data o-file % ls > ls . out % lpr ls. out これで、とりあえすの目的は達成できました。出力を見 ると、カレントディレクトリにあるファイルの一覧が出力 されているはずです。ところが、 1 つ違うことがあります。 画面で ls コマンドを実行したときには横にいくつか並ん でいたはすの出力も、プリントアウトでは下記のようにす べてのファイルが縦に 1 行すっ並んでいます。 cat . c cat . sh catl . c cat2. c cat3. c cat4. c cat5. c data o-file 前回もすこしお話ししましたが、現在の出力がどんなも のに割り当てられているのかをプログラムのなかから知る ことができます。 ls コマンドは、出力先が画面でない場合 には 1 行にファイル 1 つを出力するように作られています。 なぜこのようになっているのでしようか ? たとえば、この出力にファイルがいくつあるか調べてみ るとしましよう。 wc コマンドを用いてこの出力ファイル の行数を数えれば、このディレクトリに存在するファイル 2 回にわたって標準入出力に関してお話ししてきました の数を調べることができます。普通ならば、 wc を実行した が、例題があまり具イ和勺ではなかったのでいったいどこが 結果の単語数を見ればファイルの数が分かりますが、何か 便利なのかよく分からなかったかもしれません。しかし、 の拍子に空白を含むようなおかしなファイル名が存在する 標準入出力をうまく使えば、一見したところ複雑そうにみ と結果が異なってしまいます 1 。 えることでも意外に簡単に解決できるものです。そこで、 もっと複雑なことをするときは、このように 1 行に 1 つ 今回はプログラミングとはすこし離れて標準入出力をうま のファイル名というかたちのほうが好ましいのです。もち く使いこなす方法について考えていきましよう。 ろん柔軟な ls コマンドですから、画面以外に出力すること を考えて横に並べてほしい場合には一 C というオプション を指定すれば思ったとおりの結果が得られます。逆に、画 中間ファイル 面に出力する際も 1 行に 1 つのファイル名にしたい場合に ます、カレントディレクトリにあるファイルの一覧をプ は一 1 オプションを指定します。 リントアウトすることを考えてみます。 1 この場合は、やろうとしていることが簡単なのでそんなことはないと思うかも 一覧は、 ls コマンドを使えは得られますね。また、プリ しれません。しかし、画期的な結果を生むこともあるんですよ、本当に 130 DZ-—XN#Äログラミング 3 今泉貴史 UNIX MAGAZINE 1991.1
ロセスのジョブ番号などもありませんし、 kill の引数とし て % % などを指定することもできません。そこで、あるコ マンドをバックグラウンドで実行し、あとでその実行を取 り消したいと思ったときには $ ! を使います。その場合、 k 土 11 $ ! と入力するだけでかまいません ( ps コマンドを使ってプロ / $ cat sample cat " $ $ sample sample. —v sample. -x sample. —v sample. —x: NO such file or directory sample. -v sample. -x は、 つの文字列となってしまうので、この場合、 cat コマンドに の結果です。 " $ * " ではシェルプログラムの引数全体が 1 cat " $ 紀 実行結果の最初の行は、 set —X set —V UNIX への招待⑩ ゝセス嬲リ子を調べる必要はありません ) 。 $ * や $@ には、いすれもシェルプログラム実行時の引数 がすべて置き換えられます。しかし、この 2 つにははんの 小さな違いがあります。それぞれを二重引用符で囲った場 合です。このとき、 $ * は全体が 1 つの文字列となります が、 $@ は個々の引数がそれぞれ独立した文字列となりま す。次の例を見てください。 用符のなかで使うときは注意してください。 になります。ほんのわすかな違いですが、これらを二重引 ple. -v と sample-. x という 2 つの引数が渡されること それぞれ独立した文字列となりますから、 cat には sam- ッセージが表示されています ) 。一方、 " $@ " では、引数が sample. ー x という名則のファイルはありません〃というメ という 1 つの引数が渡されます ( cat からは、、、 sample. -v シェルプログラムの強制終了 1990 年 11 月号の 154 ページで、、℃シェルのプログラ ムを強制終了する場合、プログラム中で onintr コマンド を使っておけはプログラムが終了する直前に特定の処理が できる〃と説明しました。 Bourne シェルでも、これと同し ことがおこなえます。ただし、 Bourne シェルでは trap と いうコマンドを使います。 C シェルの onintr では、そのシ ェルに対して ki Ⅱコマンドを用いたり、シェルの実行中に 強制終了のキー (CTRL-C など ) を入力した場合の処理だ けが言己丕可能でした。一方、 Bourne シェルの trap コマン / 、ゝドでは、そのシェルに対してどのシグナルを送ったときに 何をするかという言当ができます。シグナルとは、あるプ ロセスからシグナルを受けるプロセスへ送る信号やサイン のようなものと考えてください。交通信号には、赤、青、 黄色の 3 種類しかありませんが、 UNIX には ( バージョン によって異なりますが ) 数十種類の信号があります。そし て、それぞれのシグナルには ( 色ではなく ) 番号がつけられ trap コマンドは次の形式で使います。 ています。 trap " 処理 " シグナル番号 1 , シグナル番号 2 , シグナル番号れ 最初の引数は二重引用符で囲み、そのシェルがシグナル を受けたときにどのようなコマンドを実行するかを指定し ます。また、 UNIX MAGAZINE 1991.1 trap 157 のように二重引用符だけを 2 っ並べる ( ヌルを指定する )