Unix で事務処理を - 初心者のためのガイダンス (下)

1.6 cron

cron は、Unix のタイマ機構として、指定された時刻に、 指定されたコマンドを実行する。 技術分野で自動計測を行う場合などにも、よく使うが、 事務処理の分野でも、たとえば、毎日、 一定時刻に、受注残を自動集計して、時系列ファイルに追加する等、 目が醒めるような応用がある。

  注残集計プログラム >>chuzan
といった文字列を、crontab ファイルに登録しておくだけで済むので、まったく、 手がかからない。日常業務として、どうしても必要な、 受注データの更新だけやっていれば、 管理用のデータなど、自動的にできてしまうわけだ。

時系列ファイルは、1.1 で述べたような方法で、簡単に視覚化することができる。

1.7 文書作成ツール

nroff, troff, tbl, neqn, ms, spell, typo 等の文書作成ツールは、 Unix の中でも重要な位置を占め、これだけ使うという方も、 おられるようである。

しかし、ワードプロセッサとの決定的な違いは、これらがフィルタとして、 他のコマンドとデータ交換ができという点にあり、 Unix 特有の開いた世界構成している。

例えば、見積りの原始データを、awk で細工して、 tbl と nroff に入れ、見積書を作成するといったことがよく行われる。

ただひとつ、残念なことは、日本の場合、 写植機の関係で troff の日本語版がないことであるが、 レーザー・プリンタなどの普及で、 いずれは印刷の合理化にまで、 展開できるのではないかという気がする。

1.8 mail

メモや FAX 等、紙によるメッセージ交換と違って、受け取った方は、それを再度、 キーボードから入力しなくてもよいというのが、メイルの長所である。

Unix の場合、データの加工が容易なので、メイルによるメッセージ交換が、 極めて効果的で、多分、メイルだけ単独で使おうとしたら、 あまりありがたい機能とは、思わないのではないだろうか?

Unix は、常にそのシステム全体として、意味を持つようである。

他人あてのメイル以外に、自分あてメイルを使うことも多く、例えば、 毎朝のシステム立ち上げ時などに、その日に発送しなければならない品物のリストを、 自分あてのメイルにしたりすることが、よく行われるが、 これは過負荷や老化による記憶力の減退を補うのに、大きな効果がある。

また、通常の業務データも、public ディレクトリを経由するより、直接、 個人あてメイルで処理するほうが良いことも多い。

1.9 プログラム開発ツール

c, yacc, lex, make, sccs といったプログラム開発ツールは、 独自のアプリケーション・プログラムの作成で、その真価を発揮する。

コンパイラのような、かなりの労力を要する仕事も、 楽に消化できるのは感激で、事務処理の場合、例えば、 部品展開や見積りなどの仕事は、 テーブルを用意するのが一般的だと思うが、 Unix の環境であれば、自家用言語による部品記述データを入力し、 最適設計を行って、部品、材料の消費量を求め、 見積りの原始データを作成するといったプログラムが、 比較的容易に作成できる。 この点は、経営上の大きな武器になると考える。

また、移植性のよさも、際だった長所で、他のシステムに持っていっても、 すぐ稼働させることができるので、安心して、 ソフトウェアの蓄積ができる。

2. Unix の足場

基本動作としてのコマンドを、パイプ・ラインで組み立てることにより、 現実の多様性に対処するという、 Unix の柔軟性を支えているのが、 一貫したテキスト・ファイルの採用である。

パイプ・ラインの成立は、コマンドとデータの独立性によるものであり、 その独立性は、実に、 この思い切った割り切りを足場として、確保されている。

すなわち、Unix のコマンドのほとんどが、次のような、 可変長テキスト・ファイルを、その入力データとして、 あてにしていることに注意してほしい。

FS はフィールド・デパレータ、RS はレコード・セパレータであるが、 これらを含めて、ファイルのすべての文字は、 エディタで、直接、操作することができる。

フィールド・セパレータは、space か tab を基本として、 フィールドの途中に空白文字を必要んとする場合は、colon を使うのが習慣である。

レコード・セパレータは、原則として、改行文字を使い、 何行かをまとめて 1 レコードとする場合は、空白行を使うのが明解で、 awk には、この種の構造(マルチ・ライン・レコード)を、サポートする機能がある。

改行文字の実態は、端末からの入力では CR、 ディスク上では LF になる。 また、端末からの入力では、EOT がファイルの終りを表す。

この種のファイルの実物は、先程の /etc/crontab の他、/etc/passwd 等、 システムのあちこちにあるので、見付けてみてください。 file コマンドを使って、先程のような、sh スクリプトを作るとよいだろう。

よくぞ、ここまで割り切ったと思うような、ファイル構造であるが、 こでまた、エディタが生きてくる。 エディタそのものが、汎用のツールになるわけだ。 マスタ・ファイルさえ、エディタでいじれるということに感動する。

Unix 上で事務処理を行う場合も、当然、このファイル構造に従うべきで、 これ以外の構造にするときは、よくよく考えてからにすべきだ。 Unix のすばらしい機能のうち、必ず、何かを失い、 その代償を見出すのは、極めて、困難だといって、過言ではない。

万一、バイナリ・データを使用する場合は、 テキスト・ファイルへの変更と、元に戻すためのプログラムを用意しておく。 事務処理における通常のデータであれば、伝統的な、バイナリの固定長ファイルが、 特別コンパクトになるということはない。 これは、名前等の可変長部分があるためである。

また、最初にシステムを組み立てるときは、 あまり細部まで考える必要はないように思えるが、 Unix は、データの加工が容易であるから、 一度、ディスクに入れてしまえば終り、というところがあって、 他の OS のように、システム設計を厳密にやらないと、 大きな無駄を出すということはない。 データ構造を変えたければ、容易に、変えることができる。

3. いくつかのアイデア

Unix 上の事務処理は、バッチ処理が原則である。BASIC で育った方は、 対話型の処理を好むようで、エディタでデータを作成し、 フィルタで加工するという、バッチ処理の考え方に、 抵抗を感ずるケースが多いようである。

しかし、対話型処理は、自動化をあきらめるという前提でしか、 成立しないことに注意してほしい。

バックグラウンドで処理したり、無人化したりすることはできない。 バッチでできることは、バッチでするというのが、原則である。

事務処理のうち、かなりの部分がパイプ・ラインによる、 単純なフィルタリングで対応できるが、 パイプでつながらないときは、一時ファイルを使う。 これは、例えば、

  /tmp/$$
といった、他と一致しないユニークな名前のファイルに、 途中のデータを書き出し、用済み後消去するもので、 Unix の場合、ディスクの一部は、この種のメモ代わりに使われるのが普通である。 ファイルは、いとも簡単に作ったり、消したりできるので、 通常、紙と鉛筆は要らなくなる。

sh の手続きとして、、一時ファイルを使う場合は、 手続きの終りと、割り込みが入ったとき、 trap コマンドで消去するようにしておくのが普通である。

3.2 マッチング

マスタ・ファイルとトランザクション・ファイルと呼ばれる 2 つのソートされファイルから、新しいファイルを合成する、通常、 マッチングと呼ばれるプロセスは、事務処理の典型であるが、これは、 パイプ・ラインで処理するわけにはゆかない。

awk を使うときは、データ数が少なく、データをメモリにおけるという条件であれば、 file1 をトランザクション・ファイル、 file2 を更新すべきマスタ・ファイルとして、

  awk '
  FILENAME == "file1" { 更新データを記憶 }
  FILENAME == "file2" { マスタ・ファイルを更新 }
  ' file1 file2
といった方法で対処できる。3 つ以上のファイルを使うことも多い。

トランザクション・データがメモリに収まらないときは、 次のようにすることも可能である。

  join file1 file2 | awk '
  {
     処理プログラム
  }'
マッチングの処理は、C で書くことも多いが、 その場合は、関数へのポインタを使って、 フロー・コントロールの部分を、ライブラリ関数に分離しておくと、楽になる。

3.3 排他制御

在庫や会計といった、事務処理における、基本的なファイルの多くは、 多数の人々が、同時に更新できるようにしておくのが普通であるが、 そのためには、排他制御を行わなければならない。

System V より前の Unix では、ロック・ファイルを使うのが普通で、 例えば、次のようになる。

  int fd;
  ..
  while ((fd = creat("lock", 0)) < 0)
    sleep(1);
  close(fd);
  クリティカルな処理
  inlink("loack");
  ..
これは、書き込み禁止のファイルを再作成しようとすると、 エラーになることを利用している。 他のプログラムがクリティカルな処理を行っている場合は、 ただ待つ以外に、他のことをやるかとか、 実行そのものをやめてしまうといったことも、良くおこなわれる。

System V の Unix では、セマフォやプロセス間通信の機能があるので、 それらを使うこともできるが、 ロック・ファイルにも、捨て難いところがあって、 ロック・ファイルで間に合う場合は、 ロック・ファイルを使うほうが良いように思う。

3.4 インデックスファイル

事務処理のデータには、即時更新を必要とするものもたくさんあって、 そのための手段として最も一般的なのは、インデックス・ファイルだが、 これはもともと、Unix にはないので、自分で作るしかない。

しかし、ファイルそのものは、lseek() や fseek() といった関数で、 ランダム・アクセス可能だから、インデックス・ファイルを作成するプログラムと、 インデックス・ファイルを参照するためのライブラリ関数を、 C 言語で作ればよいだけのことで、 そこは、ソフトウェア開発マシンといった性格のある Unix であるから、 割に簡単な仕事で済む。

現在、われわれのところでは、次のようなライブラリ関数を設計して使っている。 index は、インデックス・ファイルのアクセスに必要なデータをまとめた 構造体である。

  FILE *fp;
  struct index idx;
  int opt, siz;
  char *file, *buf, *key;
  ..
  ifopen(filem idx, opt) - インデックス・ファイルのオープン
  ifclose(idx) - インデックス・ファイルのクローズ
  ifgets(buf, siz, fp, idx, key) - インデックス・ファイルによる読み込み
  ifputs(buf, fp, idx, key) - インデックス・ファイルによる書き込み
  ..
これらの関数を設計する場合、機械によっては、 メモリの境界条件に注意を払う必要がある。 また、他の Unix のコマンドとの、操作上の互換性を考慮すると、大変、 面白いものができる。

おわりに

以上、Unix を使って、事務処理をやってみようかとお考えの方、あるいは、 オフィス・コンピュータやパーソナル・コンピュータによる事務処理から、 Unix への転向を検討されている方、そして、目の前の Unix をどう使うか、 考えあぐねている方々を想定して、いくつかのヒントを述べてみた。

当社の、かっての、コンピュータ嫌いが言っていた。 「こんな便利なものを、皆、何故使わないのだろうか」と。

いつか、どこかで、Unix の世界に、飛び込んでみてください。 その、居心地の良さに、感激し、それを生み出した人々の、才能と努力に、 きっと心をうたれることと思う。

参考文献

  M.R.M.Dunsmuir and G.J.Davis,- Programming UNIX System
	(Macmillan G.B.R)

  Axel T.Schreiner, H.George Friedman, Introduction to Compiler Construction with UNIX
	(Prentice Hall, USA)

  Al Kelly, Ira Pohl,- A Book on C
	(Benjamin/Cummings, USA)

平林 浩一, 1985-10 (雑誌 Computer Report 1985/10)