2006/07/01 改訂(関連ツール)
2004/12/26 改訂(関連ツール)
2004/12/24
Rit (Rc in text) はテキスト中に埋め込まれた Rc コマンドを処理するプログラムです。主要な用途は CGI プログラムの作成で HTML 文書にコマンドを埋め込みホスト側でダイナミックに HTML 文書を生成するのに使えます。
同じ趣旨のプログラムとして有名なのは PHP です。Plan 9 では PHP 自体はまだ移植されていませんが、Rit は Plan 9 の Web サーバである Pegasus によくなじみます。すなわち Rit の中では Rc の全ての機能を使用できて、コマンドのアクセス空間の制限は Pegasus がかけます。
筆者は Pegasus の CGI ツールとして、テキスト中に埋め込まれたコマンドを処理するプログラムとして Dx を添えていましたが、Dx には強い制限( I/O の切り替えやパイプの処理などができない)がありました。今回の Rit は、Dx で採用されたアプローチをやめて、コマンド部分は直接 Rc に処理させる事によって Rc と完全な互換性が保証され、遥かに強力になり、かつプログラム自体は遥かにシンプルになっています。
Rit は http://plan9.aichi-u.ac.jp/netlib/cmd/ から手に入ります。
Rit テキストの中ではただ1つの記号 $ が特殊な意味を持っています。
Rit ver1.2 のコマンドシンタックスは
rit [-Dbes] [file [arg ... ]]
です。
file は Rit 形式のテキストファイルです。このファイルは一種のスクリプトであり、arg たちは Rit のテキストファイルに埋め込まれた Rc スクリプトに渡されます。ファイル名 "." は特殊で標準入力を意味します。
オブション e で Rc スクリプトが標準エラーに何か出力した場合には終了します。なおオプション無しの Rit の実行では標準エラーに exit が出力されると終了します。すなわち
${echo exit >[1=2]; exit}
で処理が終了します。なお、exit を実行すると Rc は終了するので、その次にRc スクリプトが実行されると Rit はエラー終了します。すなわち
${exit} ${}
でも Rit が終了します。
オプション D はディバッグ用、オブション s は file の先頭一行の処理をスキップします。Rc の中で $0 はファイル file のパスを与えますが、オプション b によって $0 はファイルの base name になります。
Rc コード領域に Rc スクリプトを書きます。
例
Date: ${date}
この文は Rit によって次のように変換されます。
Date: Thu Dec 23 10:17:10 JST 2004
改行が2個付いた事に注意しよう。1つは date コマンドから、もう1つはテキスト領域の改行記号から。コマンドが発行する改行記号を抑制したい場合には
${date} continues nest line ${date}$ continues same line.
のように "}" の次に "$" を付けます。すると結果は
Thu Dec 23 10:17:10 JST 2004 continues nest line Thu Dec 23 10:17:10 JST 2004 continues same line.
となります。
テキスト領域の中の1個の $ に続く英字、数字、下線記号('_') から構成される文字列は変数です。
User: $user This is equivalent to User: ${echo -n $user}
この文は Rit によって次のように変換されます。
User: arisawa This is equivalent to User: arisawa
テキスト領域の行末の1個の $ 記号は改行を抑制します。例えば
This line has NL escape. $ next line.
この文は Rit によって次のように変換されます。
This line has NL escape. next line.
多くの Rc コマンドは NL を生成します。これを抑制したい場合には } に続けて $ 記号を書きます。
${pwd}$ this line will be next of pwd line. ${pwd}$$ this line will stays in the same pwd line.
この文は Rit によって次のように変換されます。
/usr/arisawa/src/pegasus-2.1/rit this line will be next of pwd line. /usr/arisawa/src/pegasus-2.1/ritthis line will stays in the same pwd line.
Rit は Rc の全ての機能をサポートします。例えば複数行のコマンド:
${book='Alice in Wonder Land'}$ ${echo -n 'echo test of multi-line: line1: Carrol''s book: line2: '$book' line3: and we can use { and } in rc strings' } Back slash new line escape in Rc command will work: ${echo -n one\ two }
この文は Rit によって次のように変換されます。
echo test of multi-line: line1: Carrol's book: line2: Alice in Wonder Land line3: and we can use { and } in rc strings Back slash new line escape in Rc command will work: one two
Rc の 'if' 命令はもちろん:
${ if(~ $user arisawa) echo ARISAWA if not echo NOT }$
この文は Rit によって次のように変換されます。
ARISAWA
swicth 命令ももちろん
${switch($user){ case arisawa echo ARISAWA case * echo NOT }}$
この文は Rit によって次のように変換されます。
ARISAWA
この例では { と } のネストが現れています。
コメントは NL まで続きます。これも Rc の動作と同じです。
${# This is a comment up to NL } this is also a part of comment # this is also a comment } # invisible ${# comment line1 terminated by Rc NL escape\ comment line2 } # invisible $${# This isn't a comment but a part of text }
この文は Rit によって次のように変換されます。
# invisible # invisible ${# This isn't a comment but a part of text }
2個以上の $ 記号の列は次のように処理されます。もしも $ 記号の列に変数名が続いたときには $ 記号が1個捨てられます。それゆえ
それ以外の場合には $$$$ は変換されません。
$0 は特殊です。これは処理中の Rit テキストファイルを意味します。そして $1, $2, ... は引数です。$ に続く特殊文字は特別の扱いを受けません。特に
$, $#
はそのままです。
Rit テキストを標準入力から読み取らせると $0 は "#d/0" となっています。
term% rit . alice bob $0 #d/0 $1 alice $2 bob
ここに $0, $1, $2 は入力データ、 #d/0 alice bob は Rit による出力です。
term% cat>foo $0 $1 $2 term% rit foo alice bob foo alice bob term%
多くの場合 Rit は実行ファイルとして利用されると思われます。その場合の $0, $1, ... は次の例の通りです。
term% cat>bar #!/bin/rit -s $0 $1 $2 term% chmod 755 bar term% bar alice bob ./bar alice bob term%
もしも $0 を base name として欲しい場合には -b オプション使います:
term% cat>bar #!/bin/rit -bs $0 $1 $2 term% chmod 755 bar term% bar alice bob bar alice bob term%
Rit テキストの中の ${echo exit 'some message'>[1=2];exit} は Rit を終了させます。Rc の関数 quit が前もって Rit で次のように定義されています。
fn quit {echo exit $1 >[1=2];exit}
単に Rc コード領域で exit としても Rit は終了しませんが、次の Rc コードブロックに出会うと Rit はエラー終了します。例えば ${exit} ${} は Rit を終了させます。
term% rit ${quit} term% echo $status term%
term% rit ${quit abcd} #<exit abc> term% echo $status rit 619: abcd term%
Rit は UTF-8 または EUC コードを処理できます。しかし Rc は EUC コードは処理できません。Rc の中で日本語文字を使う可能性があるのは echo だけでしょう。しかし echo の部分は全てテキスト部分に回す事ができます。つまり Rit を使えば Rc の中で echo を使うニーズはあまりないはずです。
Rit は内部でパイプを使っています。Rc の言葉を借りると
bind -b '#|' /tmp
が実行されています。Rit テキスト中の Rc コードは /tmp/data に送られ、Rc は /tmp/data1 から Rc コードを読み取ります。従って実行中の Rc から /tmp/data と /tmp/data1 が見えます:
term% rit ${ls /tmp}
Rc の標準出力はテキスト領域の処理とコード領域の処理の同期に使用されています。
今のところありません。
2006/07/01 改訂
Plan 9 のシェルである Rc はとても良くできていて、Rit を使わなくても HTML 文書を容易に作成できます。また UNIX 環境と違ってPlan 9 ではシェルを使って安全に CGI プログラムを書けます。すなわち HTML 形式で直接文書を作成するのであれば Rit のニーズはあまりありません。
しかしながら筆者は HTML 文書を直接書いているのではなく、もっと生産性の高い形式( tt 形式)で書いてそれを HTML 形式に自動変換しています。( tt 形式の例を見たいのであれば ここをクリックしてみてください。今見ているページの原型である tt 形式が得られます。筆者のサーバにはその他多数の tt 形式の例を見ることができます。詳しくは http://ar.aichi-u.ac.jp/ptt を見てください。)
tt 形式を HTML 形式に変換するプログラム( ptt )は
に置かれています。これは 700行弱の python プログラムです。python は可読性の良い言語なので、読者の環境に合わせて容易に変更できると思います。
ptt を使うと tt 形式の中に Rit によって Rc コマンドを埋め込み、それを Rit で処理可能な HTML 形式に変換できます。詳しくは http://ar.aichi-u.ac.jp/ptt/ を見てく下さい。
Rit ver.1.2 はコメントを含めてわずか 441 行、7829 バイトの小さなプログラムです。UNIX は小さなプログラムを寄せ集めて手早く多くの事ができる柔軟なプログラミング環境を実現すべく開発されました。UNIX のシェル sh は料理におけるまな板で、この優れた機能を基に多くの小さなプログラムが有機的に統合されて来たのです。しかし現在の UNIX はそうした初期の精神が失われています。Windows の世界と同様に、多くの事をこなす統合的な大きなプログラムが幅をきかせているように思われます。
UNIX の精神をネットワーク環境で生かすには OS コードの根本的な書き換えが要求されたわけです。UNIX の精神は現在では Plan 9 が引き継いでいます。この OS の優れた機能の中でこそ Rit が生きてきます。Pegasus の下で Rit は UNIX の精神通りのやりかたで CGI プログラミングを実現します。