Subsections

26章 付録


26.1 GNU一般公有使用許諾書

「GNU一般公有使用許諾書」です. http://www.gnu.org/japan/ から辿れます. ここに載せた許諾書は既に古く, 新しいバージョンが制定されていますので注意してください.

26.1.1 日本語訳

              GNU一般公有使用許諾書
              ============

              1991 年6 月,バージョン2

        Copyright (C) 1989,1991 Free Software Foundation, Inc.
           675 Mass Ave, Cambridge, MA 02139, USA *

    ----------------------------------------------------------------------
    * 【注意】 現在、このバージョン2の発行者(FSF)住所は、正式に新
     しい住所の 59 Temple Place - Suite 330, Boston, MA 02111-1307, 
     USA に変わっている。
    ----------------------------------------------------------------------

何人も、以下の内容を変更しないでそのまま複写する場合に限り、本使用許諾
書を複製したり頒布することができます。

はじめに
--------

 ほとんどのソフトウェアの使用許諾は、ソフトウェアを共有し、変更するユー
ザの自由を奪うことを意図しています。それに対して、我々のGNU一般公有使
用許諾は、フリー・ソフトウェアを共有したり変更する自由をユーザに保証す
るためのもの、即ちフリー・ソフトウェアがそのユーザ全てにとってフリーで
あることを保証するためのものです。本使用許諾は、Free Software
Foundation のほとんど全てのソフトウェアに適用されるだけでなく、プログ
ラムの作成者が本使用許諾に依るとした場合のそのプログラムにも適用するこ
とができます。(その他の Free Software Foundation のソフトウェアのいく
つかは、本許諾書ではなく、GNUライブラリ一般公有使用許諾で保護されます。)
あなたは自分のプログラムにもこれを適用できます。我々がフリー・ソフトウェ
アについて言う場合は自由のことに言及しているのであって、価格のことでは
ありません。我々の一般公有使用許諾の各条項は、次の事柄を確実に実現する
ことを目的として立案されています。

   ・ フリー・ソフトウェアの複製物を自由に頒布できること(そして、
     望むならあなたのこのサービスに対して対価を請求できること)。

   ・ ソース・コードを実際に受け取るか、あるいは、希望しさえすれば
     それを入手することが可能であること。

   ・ 入手したソフトウェアを変更したり、新しいフリー・プログラムの
     一部として使用できること。

   ・ 以上の各内容を行なうことができるということをユーザ自身が知っ
     ていること。

 このようなユーザの権利を守るために、我々は、何人もこれらの権利を否定
したり、あるいは放棄するようにユーザに求めることはできないという制限条
項を設ける必要があります。これらの制限条項は、ユーザが、フリー・ソフト
ウェアの複製物を頒布したり変更しようとする場合には、そのユーザ自身が守
るべき義務ともなります。例えば、あなたがフリー・ソフトウェアの複製物を
頒布する場合、有償か無償かにかかわらず、あなたは自分の持っている権利を
全て相手に与えなければなりません。あなたは、相手もまたソース・コードを
受け取ったり入手できるということを認めなければなりません。さらにあなた
は、彼らが自分たちの権利を知るように、これらの条項を知らしめなければな
りません。

 我々は次の2つの方法でユーザの権利を守ります。(1)ソフトウェアに著
作権を主張し、(2)本使用許諾の条項の下でソフトウェアを複製・頒布・変
更する権利をユーザに与えます。

 また、各作成者や我々自身を守るために、本フリー・ソフトウェアが無保証
であることを全ての人々が了解している必要があります。さらに、他の誰かに
よって変更されたソフトウェアが頒布された場合、受領者はそのソフトウェア
がオリジナル・バージョンではないということを知らされる必要があります。
それは、他人の関与によって原開発者に対する評価が影響されないようにする
ためです。

 最後に、どのフリー・プログラムもソフトウェア特許に絶えず脅かされてい
ます。我々は、フリー・プログラムの再頒布者が個人的に特許権を取得し、事
実上そのプログラムを自分の財産にしてしまうという危険を避けたいと願って
います。これを防ぐために我々は、いずれの特許も、誰でも自由に使用できる
ように使用許諾されるべきか、あるいは何人に対しても全く使用させないかの、
いずれかにすべきであることを明らかにしてきました。

 複写・頒布・変更に対する正確な条項と条件を次に示します。



GNU一般公有使用許諾の下での複製、頒布、変更に関する条項と条件
================================

 1. 本使用許諾は、本一般公有使用許諾の各条項に従って頒布されるとい
    う著作権者からの告知文が表示されているプログラムやその他の作成
    物に適用されます。以下において「プログラム」とは、そのようなプ
    ログラムや作成物を指すものとし、また、「プログラム生成物」とは、
    上述した「プログラム」自身、または、著作権法下における全ての派
    生物;すなわち、その「プログラム」の全部又は一部を、そのまま又
    は変更して、且つ/又は他の言語に変換して、内部に組み込んだ作成
    物を意味します。(以下、言語変換は「変更」という用語の中に無条
    件に含まれるものとします。)本使用許諾によって許諾を受ける者を
    「あなた」と呼びます。 

    複製、頒布、変更以外の行為は本使用許諾の対象としません。それら
    は本使用許諾の範囲外です。「プログラム」を実行させる行為に関し
    て制約はありません。「プログラム」の出力は、( 「プログラム」
    を実行させて作成させたかどうかとは無関係に) その内容が「プロ
    グラム生成物」である場合に限り本使用許諾の対象となります。これ
    が当てはまるかどうかは、「プログラム」が何をするものかに依りま
    す。

 2. あなたは、どのような媒体上へ複製しようとする場合であっても、入
    手した「プログラム」のソース・コードをそのままの内容で複写した
    上で適正な著作権表示と保証の放棄を明確、且つ適正に付記する場合
    に限り、複製又は頒布することができます。その場合、本使用許諾及
    び無保証に関する記載部分は、全て元のままの形で表示してください。
    また、「プログラム」の頒布先に対しては、「プログラム」と共に本
    使用許諾書の写しを渡してください。複製物の引き渡しに要する実費
    は請求することができます。また、あなた独自の保証を行なう場合は
    それを有償とすることができます。

 3. 次の各条件を全て満たしている限り、あなたは、「プログラム」又は
    その一部分を変更して「プログラム生成物」とすることができ、さら
    に、変更版や右作成物を上記第2項に従って複製又は頒布することも
    できます。

    (a)ファイルを変更した旨とその変更日とを、変更したファイル上
       に明確に表示すること。

    (b)変更したか否かを問わず、凡そ「プログラム」又はその一部分
       を内部に組み込んでいるか又はそれから派生した生成物を頒布
       する場合には、その全体を本使用許諾の条項に従って第三者へ
       無償で使用許諾すること。

    (c)変更したプログラムが実行時に通常の対話的な方法でコマンド
       を読むようになっているとすれば、最も普通の方法で対話的に
       そのプログラムを実行する時に、次の内容を示す文言がプリン
       タへ印字されるか、或いは画面に表示されること。

       ・適切な著作権表示。
       ・無保証であること(あなたが独自に保証する場合は、その旨)。
       ・頒布を受ける者も、本使用許諾と同一の条項に従って「プロ
        グラム」を再頒布できること。
       ・頒布を受ける者が本使用許諾書の写しを参照する方法。

       (例外として、「プログラム」自体は対話的であっても起動時
       の文言を通常は印字しないのならば、あなたの「プログラム生
       成物」はこのような文言を印字する必要はありません。)

    これらの要件は変更された作成物にも全て適用されます。その変更版
    の或る部分が「プログラム」の派生物ではなく、しかもそれ自体独立
    で異なる作成物だと合理的に考えられる場合、あなたがそれらを別の
    作成物として頒布した時は、本使用許諾とその条項はそれらの部分に
    は適用されません。しかし、それらを「プログラム生成物」の一部と
    して頒布する場合は、全体が本使用許諾の条項に従って頒布されなけ
    ればならず、使用許諾を受ける他の全ての者に対する許諾もプログラ
    ム全体にわたって与えられなければならず、結果として、誰が書いた
    かにかかわらず、全ての部分に本使用許諾が適用されなければなりま
    せん。

    このように、本条項の意図するところは、完全にあなたによって書か
    れた作成物について、権利を要求したり、あなたと権利関係を争うこ
    とではありません。むしろその目的は、作成物が「プログラム生成物」
    である場合にその派生物や集合物の頒布を規制することにあります。

    さらに、「プログラム」(又は「プログラム生成物」) と「プログ
    ラム生成物」とはならない他のプログラムとを、単に保管や頒布のた
    めに同一の媒体上にまとめて記録したとしても、本使用許諾は他のプ
    ログラムには適用されません。

 4. あなたは、以下のうちいずれか1つを満たす限り、上記第2項及び第
    3項に従って「プログラム」(又は、上記第3項で言及している「プ
    ログラム生成物」)をオブジェクト・コード又は実行可能な形式で複
    製及び頒布することができます。

    (a)対応する機械読み取り可能なソース・コード一式を一緒に引き
       渡すこと。その場合、そのソース・コードの引き渡しは上記第
       2項及び第3項に従って、通常ソフトウェアの交換に用いられ
       る媒体で行なわれること。

    (b)少なくとも3年間の有効期間を定め、且つその期間内であれば
       対応する機械読み取り可能なソース・コード一式の複製を、ソー
       ス頒布に関わる実費以上の対価を要求せずに提供する旨、及び
       その場合には上記第2項及び第3項に従って、通常ソフトウェ
       アの交換に用いられる媒体で提供される旨を記載した書面を、
       第三者に一緒に引き渡すこと。

    (c)対応するソース・コード頒布の申し出に際して、あなたが得た
       情報を一緒に引き渡すこと。(この選択肢は、営利を目的とし
       ない頒布であって、且つあなたが上記の(b)項に基づいて、
       オブジェクト・コード或いは実行可能形式のプログラムしか入
       手していない場合に限り適用される選択項目です。)

    なお、ソース・コードとは、変更作業に適した記述形式を指します。
    また、実行可能形式のファイルに対応するソース・コード一式とは、
    それに含まれる全モジュールに対応する全てのソース・コード、及び
    あらゆる関連のインタフェース定義ファイル、及び実行を可能にする
    コンパイルとインストールの制御に関する記述を指します。特別な例
    外として、実行可能なファイルが動作するオペレーティング・システ
    ムの主要な構成要素(コンパイラ、カーネルなど) と共に(ソース・
    コード又はバイナリのどちらかで) 頒布されているものについては、
    その構成要素自体が実行形式に付随していない場合に限り、頒布され
    るソース・コードに含める必要はありません。

    実行可能形式またはオブジェクト・コードの頒布が、指示された場所
    からの複製のためのアクセス権の賦与である場合、同じ場所からのソー
    ス・コードの複製のための同等なアクセス権を賦与すれば、たとえ第
    三者にオブジェクト・コードと共にソースの複製を強いなくとも、ソー
    ス・コードを頒布したものとみなします。

 5. 本使用許諾が明示的に許諾している場合を除き、あなたは、「プログ
    ラム」を複製、変更、サブライセンス、頒布することができません。
    本使用許諾に従わずに「プログラム」を複製、変更、サブライセンス、
    頒布しようとする行為は、それ自体が無効であり、且つ、本使用許諾
    があなたに許諾している「プログラム」の権利を自動的に消滅させま
    す。その場合、本使用許諾に従ってあなたから複製物やその権利を得
    ている第三者は、本使用許諾に完全に従っている場合に限り、引続き
    有効な使用権限を持つものとします。

 6. あなたはまだ同意の印として署名していないので、本使用許諾を受け
    入れる必要はありません。しかし、あなたに「プログラム」又はその
    派生物を変更又は再頒布する許可を与えるものは本使用許諾以外には
    ありません。これらの行為は、あなたがもし本使用許諾を受け入れな
    いのであれば、法律によって禁じられます。従って、あなたが「プロ
    グラム」(又は「プログラム生成物」)の変更又は頒布を行えば、そ
    れ自体であなたは本使用許諾を受け入れ、且つ、「プログラム」又は
    その「プログラム生成物」の複製、頒布、変更に関するこれらの条項
    と条件の全てを受け入れたことを示します。

 7. あなたが「プログラム」(又はその「プログラム生成物」)を再頒布
    すると自動的に、その受領者は、元の使用許諾者から、本使用許諾の
    条項に従って「プログラム」を複製、頒布、変更することを内容とす
    る使用許諾を受けたものとします。あなたは、受領者に許諾された権
    利の行使について、さらに制約を加えることはできません。あなたに
    は、第三者に本使用許諾の受け入れを強いる責任はありません。

 8. 裁判所の判決、又は特許侵害の申し立て、又は(特許問題に限らない)
    何らかの理由の結果として、あなたに課せられた条件が本使用許諾と
    相入れないものであったとしても(裁判所の命令、契約、その他によ
    るものであれ)、本使用許諾の条件が免除されるものではありません。
    本使用許諾による責務と、その他の何らかの関連責務を同時に満たす
    態様で頒布することができないならば、あなたは「プログラム」を全
    く頒布してはいけません。例えば、特許権の内容が、あなたから直接
    又は間接に複製を受け取った全ての人に使用料のないプログラムの再
    頒布を許さないものであれば、あなたがかかる特許上の要請と本使用
    許諾の両方を満足させる方法は、「プログラム」の頒布を完全に断念
    することだけです。

    本条項の或る部分が何らかの特別な状況下で無効または適用不可能に
    なった場合、本条項のその他の残りの部分が適用されるように意図さ
    れており、また、本条項は全体としてその他の状況に当てはまるよう
    に意図されています。

    本条項の目的は、特許やその他の財産権を侵害したり、そのような権
    利に基づく主張の妥当性を争うようにあなたに勧めることではありま
    せん。本条項の唯一の目的は、フリー・ソフトウェアの頒布システム
    の完全性を守ることで、それは公有使用許諾の実践によって履行され
    ます。多くの人々が、このシステムの一貫した適用を信頼して、この
    システムを通じて頒布されている幅広い範囲のソフトウェアに惜しみ
    ない貢献をしてくれました。作成者や寄贈者が他の何らかのシステム
    を通じてソフトウェアを頒布したいと決めることは彼らの自由意志で
    あり、使用許諾を受ける者はその選択を強いることはできません。

    本条項は、本使用許諾の他の条項の意味内容が何であるかを完全に明
    らかにすることを意図しています。

 9. 「プログラム」の頒布・使用が、ある国において特許又は著作権で保
    護されたインタフェースのどちらかで制限される場合、「プログラム」
    を本使用許諾下においた原著作権保持者は、その国を除外する旨の明
    示的な頒布地域制限を加え、それ以外の(除外されない) 国に限定
    して頒布が許されるようにすることができます。そのような場合、そ
    の制限を本使用許諾の本文にあたかも書かれているかのように本使用
    許諾の中に組み入れられるものとします。

10. Free Software Foundation は随時、本一般公有使用許諾の改訂版、
    又は新版を公表することがあります。そのような新しいバージョンは、
    現行のバージョンと基本的に変わるところはありませんが、新しい問
    題や懸案事項に対応するために細部では異なるかもしれません。

    各バージョンは、バージョン番号によって区別します。「プログラム」
    中に本使用許諾のバージョン番号の指定がある場合は、その指定され
    たバージョンか、又はその後に Free Software Foundation から公表
    されているいずれかのバージョンから1つを選択して、その条項と条
    件に従ってください。「プログラム」中に本使用許諾のバージョン番
    号の指定がない場合は、Free Software Foundation が公表したどの
    バージョンでも選択することができます。

11. 「プログラム」の一部を頒布条件の異なる他のフリー・プログラムに
    組み込みたい場合は、その開発者に書面で許可を求めてください。 
    Free Software Foundation が著作権を持っているソフトウェアにつ
    いては、 Free Software Foundation へ書面を提出してください。こ
    のような場合に対応するために我々は例外的処理をすることもありま
    すが、その判断基準となるのは、次の2つの目標の実現に合致するか
    否かという点です。即ち、1つは我々のフリー・ソフトウェアの全て
    の派生物をフリーな状態に保つことであり、もう1つはソフトウェア
    の共有と再利用とを広く促進させることです。


無保証
------

12. 「プログラム」は無償で使用許諾されますので、適用法令の範囲内で、
    「プログラム」の保証は一切ありません。著作権者やその他の第三者
    は全く無保証で「そのまま」の状態で、且つ、明示か暗黙であるかを
    問わず一切の保証をつけないで提供するものとします。ここでいう保
    証とは、市場性や特定目的適合性についての暗黙の保証も含まれます
    が、それに限定されるものではありません。「プログラム」の品質や
    性能に関する全てのリスクはあなたが負うものとします。「プログラ
    ム」に欠陥があるとわかった場合、それに伴う一切の派生費用や修理・
    訂正に要する費用は全てあなたの負担とします。

13. 適用法令の定め、又は書面による合意がある場合を除き、著作権者や
    上記許諾を受けて「プログラム」の変更・再頒布を為し得る第三者は、
    「プログラム」を使用したこと、または使用できないことに起因する
    一切の損害について何らの責任も負いません。著作権者や前記の第三
    者が、そのような損害の発生する可能性について知らされていた場合
    でも同様です。なお、ここでいう損害には通常損害、特別損害、偶発
    損害、間接損害が含まれます(データの消失、又はその正確さの喪失、
    あなたや第三者が被った損失、他のプログラムとのインタフェースの
    不適合化、等も含まれますが、これに限定されるものではありません)。


    以上


注意
**

 英文文書 (GNU General Public License) を正式文書とする。この和文文書
は弁護士の意見を採り入れて、できるだけ正確に英文文書を翻訳したものであ
るが、法律的に有効な契約書ではない。

和文文書自体の再配布に関して
**************

 いかなる媒体でも次の条件がすべて満たされている場合に限り、本和文文書
をそのまま複写し配布することを許可する。また、あなたは第三者に対して本
許可告知と同一の許可を与える場合に限り、再配布することが許可されていま
す。

   ・受領、配布されたコピーに著作権表示および本許諾告知が前もって載
    せられていること。 

   ・コピーの受領者がさらに再配布する場合、その配布者が本告知と同じ
    許可を与えていること。

   ・和文文書の本文を改変しないこと。


------------------------------------------------------------------------------

あなたの新しいプログラムにこれらの条項を適用する方法
==========================

 あなたが新しくプログラムを作成し、それを公用に供したい場合は、プログ
ラムをフリー・ソフトウェアにして、全ての人々が以上の各条項に従ってこれ
を再頒布や変更をすることができるようにするのが最良の方法です。

 そうするためには、プログラムに以下の表示をしてください。その場合、無
保証であるということを最も効果的に伝えるために、ソース・ファイルの冒頭
にその全文を表示すれば最も安全ですが、その他の方法で表示する場合でも、
「著作権表示」と全文を読み出す為のアドレスへのポインタだけはファイル上
に表示しておいてください。

  <プログラム名とどんな動作をするものかについての簡単な説明の行>
   Copyright(C) 19○○年、<著作権者名>

   本プログラムはフリー・ソフトウェアです。あなたは、Free Software
   Foundation が公表したGNU 一般公有使用許諾の「バージョン2」或い
   はそれ以降の各バージョンの中からいずれかを選択し、そのバージョン
   が定める条項に従って本プログラムを再頒布または変更することができ
   ます。

   本プログラムは有用とは思いますが、頒布にあたっては、市場性及び特
   定目的適合性についての暗黙の保証を含めて、いかなる保証も行ないま
   せん。詳細についてはGNU 一般公有使用許諾書をお読みください。

   あなたは、本プログラムと一緒にGNU 一般公有使用許諾の写しを受け取っ
   ているはずです。そうでない場合は、Free Software Foundation, Inc.,
   675 Mass Ave, Cambridge, MA 02139, USA * へ手紙を書いてください。

    ----------------------------------------------------------------------
    * 【注意】 現在、このバージョン2の発行者(FSF)住所は、正式に新
     しい住所の 59 Temple Place - Suite 330, Boston, MA 02111-1307, 
     USA に変わっている。
    ----------------------------------------------------------------------

   


 また、ユーザが電子メイルや書信であなたと連絡をとる方法についての情報
も書き添えてください。

 プログラムが対話的に動作する場合は、対話モードで起動した時に次のよう
な短い告知文が表示されるようにしてください。

   Gnomovision バージョン69、Copyright(C)19○○年 <著作権者名>

   Gnomovision は完全に無保証です。詳細は show w とタイプしてくださ
   い。これはフリー・ソフトウェアなので、特定の条件の下でこれを再頒
   布することができます。詳細は show c とタイプしてください。


 上記のshow w やshow c は各々、本一般公有使用許諾の関連する部分を表示
するコマンドを指します。もちろん、あなたが使うこれらのコマンドはshow w 
やshow c といった呼び名でなくても構いません。さらに、それらのコマンド
はあなたのプログラムに合わせる為に、マウスでクリックしたりメニュー形式
にすることもできます。

 また、必要と認めた場合には、あなたの雇い主(あなたがプログラマとして
働いている場合) や在籍する学校から、そのプログラムに対する「著作権放棄」
を認めた署名入りの書面を入手してください。ここにその文例を載せます。名
前は変えてください。


   Yoyodyne, Inc. は、James Hacker が開発したプログラム
   `Gnomovision' (コンパイラにつなげるプログラム) についての著作権
   法上の全ての権利を放棄する。

   <Ty Coon の署名>, 1 April 1989
   Ty Coon, 副社長


 本一般公有使用許諾は、あなたのプログラムを財産権の対象となっている他
のプログラムに組み込むことは認めていません。あなたのプログラムがサブルー
チン・ライブラリであって、あなたがそのライブラリを財産権の対象となって
いる他のアプリケーションとリンクさせることによって、さらに有用なものに
しようとする場合には、本使用許諾書の代わりに、GNU ライブラリ一般公有使
用許諾書に従ってください。

------------------------------------------------------------------------------


26.2 有害な csh プログラミング

Path: coconuts.jaist!wnoc-tyo-news!newsfeed.btnis.ad.jp!np0.iij.ad.jp!news.iij.ad.jp!rim.or.jp!tamaru-news!kuee-news!kuis-news!news.cs.ritsumei.ac.jp!odins-suita!chiba-ns!sakunami!Makino-Lab.cc.tohoku.ac.jp!not-for-mail
From: hiroki@aso.ecei.tohoku.ac.jp (Hiroki Mori)
Newsgroups: fj.archives.documents
Subject: Csh Programming Considered Harmful (in Japanese)
Supersedes: <5s83cm$rrg$1@dp-cc.cc.tohoku.ac.jp>
Followup-To: fj.unix
Date: 30 Sep 1997 01:50:16 +0900
Organization: Aso Lab., Dept of Comm., Tohoku Univ., Sendai, Japan
Lines: 574
Sender: hiroki@uma.aso.ecei.tohoku.ac.jp
Expires: 31 Dec 1997 23:30:00 +0900
Message-ID: <60om88$c50$1@dp-cc.cc.tohoku.ac.jp>
NNTP-Posting-Host: uma.aso.ecei.tohoku.ac.jp
X-Newsreader: Gnus v5.1
Xref: coconuts.jaist fj.archives.documents:1127

Archive-name: csh-whynot-jp
Version: $Id: csh-whynot.euc,v 1.3 1997/09/28 14:22:53 hiroki Exp $

この記事は、comp.unix.shell などに定期的に投稿されている「なぜ csh で
プログラムを書くのが良くないのか」(原題 "Csh Programming Considered
Harmful," 原著者 Tom Christiansen)という記事を日本語に翻訳したものです。
原文は、perl.com の /pub/perl/versus/csh-whynot.gz から anonymous FTP 
で入手できます。この日本語訳は、次のバージョンに基づいてなされました。

csh-faq,v 1.7 95/09/28 12:52:17 tchrist Exp Locker: tchrist

日本語訳は、http://www.aso.ecei.tohoku.ac.jp/~hiroki/csh-whynot.euc か
ら入手することもできます。誤訳、不明瞭な点などのご指摘は、NetNews およ
び email でお受けします。なお、翻訳にあたっては
  田仲@ケイケン様
  鈴木@OTSL様
  日下部陽一様
からご助言をいただきました。ここに記して感謝します。

          *** 有害な csh プログラミング ***

       結論: csh はプログラミングにはまったく向かないツールであり、
             そのような目的に使うことは厳しく禁じられるべきである!

何かのテストやインストールスクリプト、さまざまなハッキングなどに csh 
を使う人々を見て愕然とすることが私にはよくあります。Bourne シェルに十
分習熟していないと /etc/rc や .cronrc といったファイルでミスをするとい
うことが知られています。これらのファイルは Bourne シェル言語で書かなけ
ればならないので、問題なのです。

csh に魅力を感じるのは、条件文がより C ライクなせいです。それで、障害
の一番少ない道ということで csh でスクリプトを書くことになります。悲し
いかな、これは見込み違いの選択で、しかもそのプログラマはめったにそのこ
とに気がつきさえしません。それは、やらせたいと思う単純な作業の多くが
csh ではやっかいだったり、時には不可能だったりするということがわかった
としても同じなのです。


1. ファイル記述子

csh プログラミングにおいて直面する最もありがちな問題は、ファイル記述子
(訳注1)の操作ができないことです。できるのは、標準入力または標準出力を
リダイレクトすること、または標準エラーを標準出力へ複製することだけです。
Bourne 互換シェルを使えば、もっと変化に富んだことが可能です。

1a. ファイル書き込み

Bourne シェルでは、任意のファイル記述子をオープンまたは複製できます。
たとえば、

    exec 2>errs.out

というのは、これ以降標準エラーが errs.out ファイルに書き出されることを
意味します。

それとも、ただ単に標準エラーを捨てて標準出力だけをそのままにしたいとい
うのならどうしましょうか? とても簡単な操作ですよね。

    cmd 2>/dev/null

これは Bourne シェルで動作します。csh では、次のような情けないやり方し
かありません。

    (cmd > /dev/tty) >& /dev/null

しかし、標準出力が /dev/tty だと決めつけて良いのでしょうか。だから、こ
れは間違いです。この単純な操作は、csh には*不可能*なのです。


同様に、csh スクリプトではエラーメッセージを適切に標準エラーに出力する
ことができません。Bourne シェルなら、こんなふうに書けるでしょう。

    echo "$0: $file が見つかりません" 1>&2

しかし、csh では標準出力を標準エラーにリダイレクトすることはできません。
だから、結局次のようなばかばかしいものを書くはめになるのです。

    sh -c 'echo "$0: $file が見つかりません" 1>&2'

1b. ファイル読み込み

csh においては、端末からの入力を得るには一行入力 $< を使うしかありませ
ん。もしここで標準入力をリダイレクトしたとしたら? おあいにくさま、やっ
ぱり端末からの入力になってしまいます。これは、この場合実際にはリダイレ
クトはできないということです。さて、Bourne シェルのread 文を使うと、標
準入力から読みこみ、しかもリダイレクションも取りこむことができます。こ
れは次のようなことができるということです。

    exec 3<file1
    exec 4<file2

こうすると、ファイル記述子 3 から読むことによって file1 の行を得たり、
ファイル記述子 4 から file2 を得ることができるようになります。最近の 
Bourne 系のシェルでは、次のようにすれば良いです。

    read some_var 0<&3
    read another_var 0<&4

read が 0 からしか読めないような古いシェルでは、こうやってごまかします。

    exec 5<&0  # 古い stdin を取っておく
    exec 0<&3; read some_var
    exec 0<&4; read another_var
    exec 0<&5  # 元に戻す


1c. ファイル記述子を閉じる

Bourne シェルでは、2>&- のようにして、開いておきたくないファイル記述子
を閉じることができます。これは /dev/null へリダイレクトするのと同じで
はありません。

1d. さらに込み入った組み合わせ

標準エラーをあるコマンドにパイプで流し、標準出力はそのままにしたいとい
うことがあるでしょう。そんなに難しくないと思いますが、どうでしょうか。
1a で述べたように、これは csh ではできません。Bourne シェルでは、この
ようにしてできます。

    exec 3>&1; grep yyy xxx 2>&1 1>&3 3>&- | sed s/file/foobar/ 1>&2 3>&-
    grep: xxx: No such foobar or directory

通常の出力は影響を受けないはずです。ファイル記述子を閉じる >&- がある
のは、何かがそのファイル記述子すべてに構っているかもしれないからです。
ここでは標準エラーを sed に送り、それから 2 に戻しています。

次のパイプラインを考えてみましょう。

    A | B | C

C が返すステータス値を知りたいとします。そう、これは簡単で、$? か、あ
るいは csh なら $status に入っています。でも、もしステータス値を A か
ら得たいのなら、ついてませんね。まあ、csh を使っていれば、ですが。
Bourne シェルでならできるのですが、それをするのは少しトリッキーです。
次のものは、私が dd の records in/out ノイズを除くためにエラー出力を 
grep -v にパイプするが、戻り値として grep のではなく dd のステータスを
返さなければならなかったときのものです。

    device=/dev/rmt8
    dd_noise='^[0-9]+\+[0-9]+ records (in|out)$'
    exec 3>&1
    status=`((dd if=$device ibs=64k 2>&1 1>&3 3>&- 4>&-; echo $? >&4) |
        egrep -v "$dd_noise" 1>&2 3>&- 4>&-) 4>&1`
    exit $status;


csh はまた、既知・未知を問わずすべてのファイル記述子を閉じてしまい、開
かれたファイル記述子を継承することを意図したアプリケーションには不向き
であることでも知られています。


2. コマンドの直交性

2a. 組み込みコマンド

csh は組み込みコマンドについてはひどいできそこないです。それらは合理的
な方法で組み合わせられないことが多いのです。次のような単純なものでさえ
そうです。

        % time | echo

ばかばかしいのですが、こんなメッセージを出さないで欲しいものです。

        Reset tty pgrp from 9341 to 26678

もっとおもしろいのもあります。

        % sleep 1 | while
        while: Too few arguments.
        [5] 9402
        % jobs
        [5]     9402 Done                 sleep |

ものによっては、シェルをハングさせてしまうかもしれません。何かを 
source している間に ^Z をタイプしたり、source コマンドをリダイレクトし
たりしてみましょう。ただ、手元に別のウィンドーを出しておくことを忘れず
に。

    % history | more

とすると、何かが起こるシステムもあるので試してみましょう。

エイリアスは、いつもそれが評価されて欲しい所で評価されるわけではありま
せん。

    % alias lu 'ls -u'
    % lu
    HISTORY  News     bin      fortran  lib      lyrics   misc     tex
    Mail     TEX      dehnung  hpview   logs     mbox     netlib
    % repeat 3 lu
    lu: Command not found.
    lu: Command not found.
    lu: Command not found.

    % time lu
    lu: Command not found.

2b. 流れ制御

次のように、流れ制御とコマンドを混在させることはできません。

    who | while read line; do
    echo "$line を読んだ"
    done

csh での複数行の構造をセミコロンを用いてまとめることはできません。次の
ことを簡単に実現する方法はありません。

    alias cmd 'if (foo) then bar; else snark; endif'

ステータス値を得るだけのために if 文でリダイレクトをすることはできません。

    if ( { grep vt100 /etc/termcap > /dev/null } ) echo ok

また、パイプさえも使えません。

    if ( { grep vt100 /etc/termcap | sed 's/$/###' } ) echo ok

しかし、これらは Bourne シェルでならうまく動作します。

    if grep vt100 /etc/termcap > /dev/null ; then echo ok; fi   

    if grep vt100 /etc/termcap | sed 's/$/###/' ; then echo ok; fi

次の合理的な構造を考えてみましょう。

  if ( { command1 | command2 } ) then
      ...
  endif

command1 の出力は command2 の入力へは行きません。両方のコマンドの出力
が標準出力に出てきます。エラーは何も起こりません。 Bourne シェルやその
クローンでは、こうすることでしょう。

    if command1 | command2 ; then
    ...
    fi


2c. 構文解析のばからしいバグ

合理的であるにもかかわらず動作しないものがあります。たとえば、次がそう
です。

    % kill -1 `cat foo`
    `cat foo`: Ambiguous.

しかし、これだと大丈夫です。

    % /bin/kill -1 `cat foo`

もし次のようにして止めたジョブがあるなら、

    [2]     Stopped              rlogin globhost

次のようにして kill できるはずです(訳注:が、実際にはできない)。

    % kill %?glob
    kill: No match

しかし、

    % fg %?glob

だと動きます。

スペースが問題となることがあります。

    if(expr)

は csh のバージョンによってはうまくいきません。ところが

    if (expr)

は大丈夫! あなたのマシンのベンダはこのバグを直そうとしたかもしれませ
んが、その csh でも次のものはやはり扱えない公算が大です。

    if(0) then
      if(1) then
          echo A: ここを通過
      else
          echo B: ここを通過
      endif
      echo この文は実行されないはずなのだが・・・
    endif


3. シグナル

csh では、SIGINT をトラップすることができるだけです。 Bourne シェルで
はどんなシグナルでも、あるいは end-of-program 終了でもトラップすること
ができます。たとえば、いろいろなシグナルに応じて中間ファイルを消去する
には、このようにします。

    $ trap 'rm -f /usr/adm/tmp/i$$ ;
        echo "ERROR: abnormal exit";
        exit' 1 2 3 15

    $ trap 'rm tmp.$$' 0   # on program exit



4. クオート

csh ではまともにクオートをすることができません。

    set foo = "Bill asked, \"How's tricks?\""

これは動作しません。これでは、引用符が混在した文字列を構成するのはとて
も難しいことです。Bourne シェルではまったく大丈夫。実は、こんなものも
大丈夫なのです。

     cd /mnt; /usr/ucb/finger -m -s `ls \`u\``

csh では二重引用符の中でドル記号をエスケープすることができません。ふう。

    set foo = "クオートした \$dollar と、していない $HOME"
    dollar: Undefined variable.

改行をクオートするためにはバックスラッシュを使う必要があり、文字列に含
めるのは本当に難しいことです。

    set foo = "あれ \
    これ";
    echo $foo
    あれ  これ
    echo "$foo"
    Unmatched ".  

何だこりゃ? Bourne シェルではこんな問題はありません。Bourne シェルで
は次のように書くこともまったく平気です。

    echo    'これは
         改行を何個か含んだ
         テキストです。'


UUCP 形式のメールアドレスをクオートするのもやりがいがあります。次の例
を考えてみましょう。

    % mail adec23!alberta!pixel.Convex.COM!tchrist
    alberta!pixel.Convex.COM!tchri: Event not found.


5. 変数の文法

大域変数(環境変数)と局所変数(シェル変数)との間には大きな違いがあります。 
csh ではそれらをセットするのにまったく異なった文法を使います。

Bourne シェルでは、
    VAR=foo cmds args
は
    (export VAR; VAR=foo; cmd args)
と、あるいは csh の
    (setenv VAR;  cmd args)
と同じです。

環境変数に対して :t, :h などを使うことはできません。次を見てください。
    echo やってみよう。 $SHELL:t

PAGER がセットされていればそれを使い、そうでなければ more を使うという
ことを、

    ${PAGER-more}
あるいは
    FOO=${BAR:-${BAZ}}

のように書けたら実に良いのですが、csh ではできません。もっと冗長になっ
てしまいます。

最新のバックグラウンドコマンドのプロセス番号を csh から得ることはでき
ません。何個ものジョブをバックグラウンドで起動させているときには、その
ようにしたいことがあるかもしれません。Bourne シェルでは、最後にバック
グラウンドで投入したコマンドの pid を $! で参照できます。

csh は環境変数を局所変数(シェル変数)にインポートするときの動作について
も怪しいです。特に HOME, USER, PATH, TERM を扱う場合はそうです。次を考
えてみましょう。

    % setenv TERM '`/bin/ls -l / > /dev/tty`'
    % csh -f

どうなるかはお楽しみ。


6. 式の評価

csh における次の文を考えてみましょう。


    if ($?MANPAGER) setenv PAGER $MANPAGER


ただ単に PAGER をセットしたいだけなのに、csh はこんなふうに中断してし
まいます。

    MANPAGER: Undefined variable.

これは、csh が常に行全体を解析し、また*評価する*からです。これはこのよ
うに書かなければなりません。

    if ($?MANPAGER) then
    setenv PAGER $MANPAGER
    endif

次も同様に問題です。

    if ($?X && $X == 'foo') echo ok
    X: Undefined variable

このため、入れ子の if 文を2,3行書くことを強いられます。これは、このよ
うな状況における「短絡」論理式を使えなくするので非常に望ましくないこと
です。もし csh がもっと C に近かったなら、この種の論理式を問題なく使え
たはずです。次の一般的な C の構文を考えてみましょう。

    if (p && p->member) 

Bourne シェルでは未定義変数は決定的なエラーとはならないため、この問題
は起きません。

csh は組み込みの数式処理機能を持ってはいるのですが、それはあなたが思う
ようなものではありません。実は、スペース依存なのです。次は誤りです。

   @ a = 4/2

しかし、これなら OK です。

   @ a = 4 / 2

csh が用いるアドホックな構文解析は、他の所でも同様にじゃまをします。次
の例を考えてみましょう。

    % alias foo 'echo こんにちは' ; foo
    foo: Command not found.
    % foo
    こんにちは



7. エラー処理

スクリプト中の誤りを、走らせる前に知ることができたら良いと思いませんか?
-n フラグはそのためにあります。文法を見てみましょう。特にこれは、あまり
ありそうもないコード片の正当性を確かめてくれる点でとても良いです。それ
なのに、これは csh の実装では動作しません。次の文を考えてみましょう。

    exit (i)

もちろん、本当はこのようにしたかったのです。

    exit (1)

または、単に

    exit 1

どちらのシェルもこれには警告を出してくれます。しかし、次のように、この
部分が if 節の中に隠れていると、csh はこのスクリプトに誤りはないと告げ
ます。一方、Bourne シェルにおける等価な構文はこのように教えてくれます。


    #!/bin/sh -n
    if (1) then
    exit (i)
    endif

    /tmp/x: syntax error at line 3: `(' unexpected



さまざまなバグ

まず1つ。

    fg %?string
    ^Z
    kill  %?string
    No match.

ありゃ。もう1つ。

    !%s%x%s

これはコアをダンプ、あるいはゴミを返します。

バッククオートを含むエイリアスがあり、それを別のエイリアス中のバックク
オートの中で使うと、コアダンプします。

次のように入力してみましょう。
    % repeat 3 echo "/vmu*"
    /vmu*
    /vmunix
    /vmunix
何だ?


もう1つあります。

    % mkdir tst
    % cd tst
    % touch '[foo]bar'
    % foreach var ( * )
    > echo "$var というファイル"
    > end
    foreach: No match.


8. まとめ


ベンダの中には csh のバグをいくつか直した(tcsh ではもっと良く直ってい
る)ところもありますが、新たなバグを付加したところも多いのです。それら
の問題のほとんどは決して解決されません。なぜならそれは、本来それらが実
際にバグだからではなく、「脳死」した設計を採用したことによる当然の帰結
だからです。そもそもが欠陥品なのです。

何かをしたくて、しかもシェルスクリプトを書く*必要*があるのなら、Bourne
シェルで書きましょう。その辺のすべての UNIX システムに載っています。し
かし、その動作はまちまちかもしれません。

他にも選択肢はあります。

Korn シェルは多くの sh 常用者に好まれているプログラミングシェルですが、
それはまだ構文解析や式評価がひどいといった Bourne シェルの設計に元々あ
る問題に悩まされています。Korn シェル、あるいはそのパブリック・ドメイ
ンなクローンおよびスーパーセット(たとえば bash)は sh ほどありふれては
いないので、ネットに投稿するシェルアーカイブをそれらで書くのは賢明とは
言えないかもしれません。1003.2 が企業に対して強制力のある真の標準になっ
たとき、状況ははるかに良くなることでしょう。そのときまで、我々はそこら
へんにあるバグあり互換性なしバージョンの sh で悩まされることでしょう。

Plan 9 のシェルである rc の構文解析と式の評価ははるかにきれいなのです
が、それはまだ広く使えるわけではないので、可搬性は大きく損なわれること
でしょう。まだ rc を出荷しているベンダはありません。

もしシェルを使う必要はなくて、単にインタプリタ型言語が欲しいだけなら、
他の多くのフリーソフト、たとえば Perl, REXX, TCL, Scheme, Python のよ
うなものを使える可能性が出てきます。とりわけ、Perl は UNIX において、
そして他の多くの処理系において、おそらく最も広く使うことができます。
Perlを標準システムと共に出荷するベンダも増えています。(comp.lang.perl
FAQ のリストを見てください。)

もし普通だったら sed や awk や sh を使うのだけれども、それらの能力を超
えているような、またはもう少し速く走らせたいような問題があり、そんなも
のを C で書くのはばかばかしいというのだったら、Perl が役に立つことでしょ
う。ネットワーク関数、バイナリデータ処理やほとんどの C ライブラリ関数
を使うことができます。また sed や awk で書いたスクリプトから Perl スク
リプトへの変換プログラムもありますし、シンボリック・デバッガもあります。
tchrist(著者)の経験則は、Makefile の大きさにおさまるようなものは
Bourne シェルで書き、それより大きいようなものは Perl で書くというもの
です。

これらの言語についての詳細(FAQを含む)については
comp.lang.{perl,rexx,tcl} を見るか、comp.lang.misc と news.answers に
ある David Muir Sharnoff によるフリーで入手可能な言語とツールの比較を
見てください。

注意: Doug Hamilton <hamilton@bix.com> による商用の小さな非UNIXシステ
ム用のプログラムがあります。彼はそれを `csh' あるいは `hamilton csh' 
と呼んでいますが、それは本当の csh に対してバグの点でも仕様の点でも互
換ではないので csh ではありません。実際、彼は大きく修正をしたのですが、
そうしたことによって、まったく異なったシェルを作ってしまったのです。

(訳注1:ファイル記述子とは、プロセスがオペレーティングシステムを介して
入出力操作を行うとき、ファイル(またはパイプ)に付与される整数。特別なファ
イル記述子として、ユーザがログインすると自動的に作成される
  0  標準入力
  1  標準出力
  2  標準エラー出力
がある。詳細は、たとえば S.R. Bourne, "The UNIX System," Addison-Wesley
などを参照。)
-- 
            東北大学工学部通信工学科阿曽研究室    森  大毅
                          (hiroki@aso.ecei.tohoku.ac.jp)



(c)1999-2013 Tetsuya Makimura