C Shell
C shell(シーシェル、csh)は、カリフォルニア大学バークレー校の大学院生だったビル・ジョイが1970年代後半に開発したUnixシェルである。1978年にジョイが配布を始めた 2BSD という BSD UNIX のリリースで広く配布されることになった[2][3]。他にアイデアやコードに貢献した者としては、マイケル・ウベル、エリック・オールマン、マイク・オブライエン、ジム・カルプがいる[4]。UNIX V6 の /bin/sh を元に作られたもので、Bourne shell (UNIX V7) と共通の先祖を持つ。 通常テキストウィンドウ内で動作するコマンドラインインタプリタであり、ユーザーがコマンドを入力するとそれに応じた処理が実行される。またシェルスクリプトと呼ばれるファイルからコマンド群を読み込むこともできる。他のUnixシェルと同様、ファイル名のワイルドカード、パイプ、ヒアドキュメント、コマンド置換、変数、条件分岐やループなどの制御構造をサポートしている。cshが1980年代の他のシェルと異なっていた点は、対話向けの機能と全体的なスタイルである。新機能によって他のシェルよりも容易に素早く使うことができた。言語としての全体的スタイルはC言語によく似ており、Unixユーザーにとっては読みやすかった。 macOS や Red Hat Linux など多くのシステムのcshは実際には改良版のtcshである。tcshの実行ファイルは "csh" と "tcsh" の両方にハードリンクされていて、どちらの名前でも同じ改良版のtcshが呼び出される。 DebianやUbuntuではcshとtcshの2種類のパッケージを用意しており、前者はオリジナルのBSD版csh[5][6]、後者は改良版のtcsh[7][8]となっている。両方をインストールした場合、cshとしてどちらを使用するかupdate-alternativesコマンドで選択できる。 tcshには、ファイル名やコマンドの補完機能、Tenexシステムに由来するコマンド行編集があり、名称の先頭の "t" は Tenex に因んでいる[9]。tcshは機能を追加しただけでオリジナルのcshを修正したわけではないので、後方互換を保っていた[10]。当初はジョイが作ったオリジナルのソースツリーからの脇枝だったが、今ではtcshが主な枝となっていて、開発が継続されている。tcshは非常に安定しているが、主に細かいバグ修正のため、およそ1年に1回の頻度で新たなリリースがなされている[11]。 設計目標と機能C shell の主たる設計目標は、C言語に似せることと、対話型利用での改良であった。 C言語風のスタイルUnixシステムはほとんど全体がCで書かれているため、C shell の第一の目標はスタイル上システム全体と一貫性のあるコマンド言語とすることだった。キーワード、括弧の利用、組み込みの式の文法、配列サポートなどは全てCの影響を強く受けている。 今ではC言語によく似た文法のスクリプト言語がいくつもあり、それらに比べればcshはそれほどC言語に似ているとは言えない。しかし80年代から90年代にかけて、特にAT&Tでスティーブン・ボーンが開発したshと比べたときの違いは著しいと見られていた。次の例は、C shell の演算子や構文のわかりやすさを示したものである。
shには式の文法が存在しない。 対照的にcshは自前で式を評価でき、高速である。可読性もよいと言われている。演算子や構文の多くはC言語のものをそのまま使っている。キーワードを逆に綴ることもなく、全体としてよりC言語に近いスタイルである。 次の例は、2の1乗から10乗までを計算するスクリプトを比較したものである。
やはりshには式の文法が存在しないため、shのスクリプトはコマンド置換とexprコマンドを使っている。C shell の @ 文(コマンド)は一種の駄洒落であり、"at-sign-ment" すなわち代入文を意味している。 最後の例は、switch文のスタイルの違いを示したものである。
shのスクリプトでは、" 対話型利用のための改良点C shell の第二の設計目標は、対話型利用の改良だった。そのため、ユーザビリティや入力の高速性を追求したいくつかの新機能を導入している。必要な結果を得るのに打ち込まなければならないキーストローク数を減らすことで、高速性を実現している。特に重要なのは、ヒストリとその編集機構、エイリアス、ディレクトリスタック、チルダ記法、cdpath、ジョブコントロール、パスハッシングである。これら新機能は人気となり、多くが他のUnixシェルにも採用された。
スクリプト言語としての C ShellC shell は行単位で操作する。各行を字句解析して空白、括弧、パイプやリダイレクトを表す記号、セミコロン、アンパサンド等で区切られた単語の並びとして認識する。 基本構文基本の文は単にコマンドを実行するものである。先頭の単語がコマンド名として認識され実行される。" 基本構文レベルでは、以下のような文法の機能が存在する。
制御構造csh は条件分岐と反復という制御構造を提供している。条件分岐としては
|
// C groups from the left
// prints 4
int i = 10 / 5 * 2;
printf( "%d\n", i );
// prints 5
i = 7 - 4 + 2;
printf( "%d\n", i );
// prints 16
i = 2 >> 1 << 4;
printf( "%d\n", i );
|
# C shell groups from the right
# prints 1
@ i = 10 / 5 * 2
echo $i
# prints 1
@ i = 7 - 4 + 2
echo $i
# prints 0
@ i = ( 2 >> 1 << 4 )
echo $i
|
C shell での括弧はビットシフト演算子と入出力リダイレクトを混同しないために使用している。どちらの言語でも括弧を使えば評価順序を明確化できる。なお先述した通り、シェル変数の値は文字列であり、@ 文などの式の中でだけ文字列を数値に変換して評価し、結果を文字列に変換して変数に格納している。
批判
いくつもの革新的機能により対話型利用では人気となったが、csh はスクリプト言語としては人気を獲得することはなかった。当初から1980年代末まで、cshはあらゆるUnixシステムに実装されていたわけではなく、shならばあらゆるUnixシステムに存在することが確実だった。したがって、様々なシステムで動作する可能性のあるスクリプトはshで書くのが賢明だった。1990年代中ごろにはcshも広く利用可能となったが、POSIXの委員会からcshをスクリプト言語として使用することに対して批判の声が挙がった[13]。すなわち、対話用とスクリプト用の推奨シェルは1つであるべきだとし、POSIXとしては KornShell を推奨するとしたのである。C shell は他にも、文法上の欠陥、機能不足、実装のまずさといった点で批判された[14][15]。
- 文法上の欠陥
- 言語定義上、不必要な矛盾が生じている。例えば、
set
、setenv
、alias
というコマンドは、ある名前と文字列または単語の並びを結びつけるという基本的に同じ機能を有している。しかし、それらには全く不必要な若干の差異がある。set
では等号を必要とするが、setenv
やalias
では等号は使わない。set
では単語の並びを括弧で囲む必要があるが、setenv
とalias
ではそうではない。同様に、if
の最後はendif
、switch
の最後はendsw
、ループ系構文では最後がend
というように意味も無く一貫性がない文法になっている。 - 機能不足
- よく言われるのは、標準入力ファイルハンドルの操作機能と関数サポートの欠如である。Bourne shell は局所変数は使えないが関数は定義できるのに対し、csh で関数に相当する機能はエイリアスしかなく、1行のコードしか定義できず、しかも制御構文の多くは途中に改行を必要とする。結果としてスタイルは似ていてもC言語のプログラムの機能をそのまま C shell で実装するのは困難である。そのため、大きなプロジェクトほどC言語や Bourne shell のスクリプトを使う傾向がある。
- 実装のまずさ
- 構文解析は場当たり的であり、多くの批判を浴びている。1970年代初めにはコンパイラ技術はそれなりに成熟しており[16]、多くの言語はトップダウンまたはボトムアップ構文解析器を使って完全に再帰的な文法を認識できるように実装されていた。C shell で場当たり的な設計となった理由は不明である。ジョイは2009年のインタビューで「Unixに関して作業を始めたとき、私は優秀なプログラマではなかった」と述べており、単にそれが答えかもしれない[17]。しかし、場当たり的な設計を選択したせいで C shell は完全再帰的ではなくなった。したがって、実現できる処理の複雑さには限度がある。
対話的にコマンドを入力して実行するぶんには快適だが、複雑なコマンドを実行させようとスクリプトを書いてみると時間がかかり、しかもよく失敗し、暗号のようなエラーメッセージを表示するか、好ましくない結果を生じることになる。例えば、C shell では制御構造間のパイプは不可能である。例えば foreach
の出力をパイプで grep
コマンドに送り込もうとしても単に機能しない。ワークアラウンドとしては、foreach
を使った部分を別のスクリプトにして構文解析の問題を回避するという手段がある。こうすれば、そのスクリプトは別のcshのプロセスとして動作するのでパイプで接続することも自由である。
別の好ましくない動作の例としてコード断片を示す。下記のスクリプトはどちらも「'myfile' が存在しないなら、'mytext' をそこに書き込む形で生成せよ」という意味である。しかし、右側の例では常に空ファイルが生成される。何故なら C shell の評価順序はコマンド行単位であり、まず入出力リダイレクトを評価することになっているためで、myfile がその際に作られてしまい、ファイルの存在を調べたときには既に存在しているためである。
# Works as expected
if ( ! -e myfile ) then
echo mytext > myfile
endif
|
# Always creates an empty file
if ( ! -e myfile ) echo mytext > myfile
|
また、エラーメッセージが貧弱だという点もよく批判されている。例えば "0 event not found" というメッセージからは何が問題なのかもわからない。
影響
ヒストリ機構、エイリアス、チルダ記法、対話的ファイル名補完、シェル内での式評価などといった機能は大きな成功だったと言え、他のUnixシェルでも採用された。しかしkshやbashなど多数の独立したクローンが生まれたshとは対照的に、cshのクローンとして知られているものは2つしかない(tcshはcshと独立して開発されたわけではなく、クローンとは言えない。tcshはビル・ジョイの書いたオリジナルのコードをベースとして機能を追加しただけである)。
アレン・ホーラブの1986年の著書 On Command: Writing a Unix-Like Shell for MS-DOS[18] では、"SH" という名前のプログラムを解説しているが、これはshではなくcshの機能と言語設計をコピーしたものである。関連するフロッピーディスクにはSHと基本的なUnix風コマンド(cat、cp、grep など)のソースコードが格納されていて、それぞれ25ドルと30ドルで販売されていた。ホーラブのSHの制御構造、式の文法、ヒストリ機構などは全て C shell と同一だった。
1988年、Hamilton Laboratories がOS/2向けに Hamilton C shell を発売した[19]。1992年には Windows NT 版をリリース[20]。Windows版はその後も活発にサポートされているが[21]、OS/2版は2003年でサポート終了している。Hamilton C shell は Nicole Hamilton が書いたもので、cshクローンとUnixユーティリティ群を含んでいる。初期のクイックリファレンスによれば[22]、「(ジョブコントロールを除く)C shell 言語全体に完全準拠」としているが、言語仕様には若干の改良が見られ、UnixとPCの差異にも対応している。最大の改良点はトップダウン構文解析を採用した点で、制御構造の入れ子やパイプ連結が可能となっている。また、プロシージャを定義でき、ブロック構造に局所変数を定義でき、浮動小数点演算もサポートしている。PC向けの改良点としては、ファイル名などのPCにおける慣習に従っており、スレッドの生成で済む部分は子プロセスを生成するのではなくスレッドで対応している。
音声認識研究の分野では C shell がスクリプト言語としてよく使われている。これはHTKというツール[23]がcshスクリプトを使っていることと関連している。
脚注
- ^ Zoulas, Christos (Jan 14 2012), tcsh-6.18 is now available 2012年1月16日閲覧。
- ^ Harley Hahn, Harley Hahn's Guide to Unix and Linux.
- ^ Berkeley Engineering Lab Notes, Volume 1, Issue 2, October 2001.
- ^ An Introduction to the C shell by Bill Joy.
- ^ https://packages.debian.org/buster/csh
- ^ https://packages.ubuntu.com/focal/csh
- ^ https://packages.debian.org/buster/tcsh
- ^ https://packages.ubuntu.com/focal/tcsh
- ^ Ken Greer (3 October 1983). “C shell with command and filename recognition/completion”. Newsgroup: net.sources. 2010年12月29日閲覧.
- ^ tcsh(1) man page
- ^ Fixes file in tcsh-6.17.00.
- ^ Re: Late Bloomers Revisited USENET post to comp.lang.misc by Piercarlo "Peter" Grandi, Dept of CS, UCW Aberystwyth, UK, Dec 17, 1989.
- ^ IEEE Standard for Information Technology, Portable Operating System Interface (POSIX), Part 2: Shell and Utilities, Volume 2. IEEE Std 1003.2-1992, pp. 766-767. ISBN 1-55937-255-9.
- ^ Csh Programming Considered Harmful by Tom Christiansen
- ^ Top Ten Reasons not to use the C shell by Bruce Barnett
- ^ David Gries (1971). Compiler Construction for Digital Computers. John Wiley & Sons. ISBN 0-471-32776-X.
- ^ Bill Joy in Conversation with Brent Schlender, Churchill Club, Santa Clara, CA, Feb 11, 2009.
- ^ Holub, Allen (1986, 1987). On Command: Writing a Unix-Like Shell for MS-DOS (Second ed.). M&T Books, Redwood City, CA. ISBN 0-934375-29-1
- ^ Hamilton, Douglas. “Hamilton C shell Announcement”. IBM Personal Systems Developer (Summer 1989): 119–121 2010年11月22日閲覧。.
- ^ Hamilton C shell for Windows Release Notes 4.0, retrieved June 19, 2010.
- ^ Oliver, Robert (2009年9月19日). “Hamilton C Shell 2009 – The Missing Shell for Windows”. 2010年2月10日時点のオリジナルよりアーカイブ。2010年6月24日閲覧。
- ^ Hamilton C shell Quick Reference. Hamilton Laboratories, Wayland, MA. (1988 - 1990 (Revised July 10, 1990)) 2010年11月22日閲覧。
- ^ htk
参考文献
- G.アンダーソン、P.アンダーソン『UNIX C SHELLフィールドガイド ビル・ジョイが開発した』落水浩一郎・大木敦雄訳、パーソナルメディア、1987年10月。ISBN 4-89362-029-0 。
- Paul DuBois『入門 csh & tcsh』鈴鹿倫之・福澤康裕訳、オライリー・ジャパン、2002年2月。ISBN 4-87311-073-4 。
- Arnold Robbins、Nelson H. F. Beebe『詳解シェルスクリプト』日向あおい訳、オライリー・ジャパン、2006年1月。ISBN 4-87311-267-2 。
- Wang, Paul (1988). An Introduction to Berkeley UNIX. Wadsworth Pub. Co.. ISBN 0-534-08862-7
- Arick, Martin R. (1993). UNIX C Shell Desk Reference. John Wiley & Sons. ISBN 0-471-55680-7
- “Introduction to C Shell Programming”. Canisius College Computer Science Department. 2010年6月23日閲覧。
関連項目
外部リンク
- 有害な csh プログラミング
- Cシェルプログラミング
- An Introduction to the C shell by William Joy.
- Linux in a Nutshell: Chapter 8. csh and tcsh.
- tcsh home page.
- historical 2BSD csh source code dated February 2, 1980.
- The Unix Tree, complete historical Unix distributions.
Portal di Ensiklopedia Dunia