今日からCGIプログラマー 《第1回》CGIを動作させてみる この自作道。デバッグはコマンド・プロンプト風味で CGIなんて要らない ……って考えてる人発見。 本当にそうだろうか。CGI入門というと、たいていの書籍は、FTPのアップロー ドやパーミッションの設定から始まり、「UNIXサーバ」だとか、「CGIの置ける プロパイダの確認」だとかいう文字が踊る。 コチコチ頭は誰だ? ■旧い考え ●CGIは、プロバイダや研究室などのサーバの中に置き、公開コンテンツを作る。 ●Perl?実行速度遅いんでしょ?やっぱCだよ。 ●Perlはリソース喰うしね。 ■新しい考え ●常時回線だもん。CGIは自宅のWindowsマシンで動かそう。 ●自分専用か、仲間専用(だから、動けばいい……バキ)。 ●実行速度もリソースも気になんない。だってマシン速いし。 ●携帯とか、どこかのPCから、自分のデータに快適アクセス。 ●もっと小規模に、LANの中や、ローカルから見れれば充分。 つまり、「公開コンテンツ」とかを考えてしまうから、「CGI、これすなわち、ア クセス・カウンタ」とか「掲示板」とかそういう発想になるワケ。 そうじゃなくて、自分のためのプログラムを、気軽に便利に作れるのがPerl+C GI。もっと楽しいもんなのよ……。 さらに、Perlは、限りなくインタープリタに近いコンパイル言語だから、パスを 変えたりするだけで、平気でUnix上でも動いたりする。こりゃ、便利。 もちろん、最初はフリーウェアをgetしたほうが話が早いだろう。だが、スクリプ トって、作れば作るだけ開発は速くなるし、フリーウェアでは、どうにも痒いところに 手が届かない場合にだけ、Perl+cgiで補うって形でも、めちゃ便利。 他人のために提供するプログラムじゃないからお気楽なもんよ。それでも、不便なフ リーウェアだけを、使って生きてくんですか? え?ひょっとしてPerlをまったく知らない?いや、ぜんぜんOK。だって、たと えば、「とほほのPerl入門」(http://tohoho.wakusei.n e.jp/wwwperl.htm)なんかで、本連載のスクリプトが何をしているか 追っかければ、すぐに使えるようになるから。 入手・設定 誌面の都合で省略するが、「jperl」「入手」でand検索をかければ、よいペ ージがいくらでも検索できる。 最初からjperlで供給されているタイプではなく、「ActivePerl 5 .XX」をインストール後、「日本語パッチ」を当てる、というスタイルでインストー ルするタイプの方法を選ぶのがコツ。 「C:\Perl\bin\MSWin32-x86-object\jperl. exe」というパスに、jperlがインストールされるのが、正式なパッケージ。実 際には、jperlよりもperlを使うことが多いのだが、ときどきjperlも便 利なので、両方欲しいところ。 で、CGIっていうのは、要するに、ブラウザ越しに動くプログラムって思えばいい 。だから、Perlだけじゃダメで、「ブラウザでアクセスしたときに応答するプログ ラム」=「Webサーバ」ってやつもインストールする必要がある。 これは、Apache(http://japache.infoscience. co.jp/index.html)と、AN HTTP Server(http: //www.st.rim.or.jp/~nakata/index.html)を 、両方、インストールしよう。どちらか片方だけにしたかったら、やはりApache だろう。 Apacheは、素直に、デフォルトの「C:\Program Files\Ap ache Group」以下にインストールしてほしい。設定の要点を書く。 @「httpd.default.conf」を「httpd.conf」にリネーム A以下、http.confを書き換える。 「DocumentRoot "C:/Program Files/Apache Group/Apache/htdocs"」を、たとえば、「DocumentR oot "C:/html"」のようにHTMLを置きたいディレクトリに書き換える 。 BAにともない、「<Directory "C:/Program File s/Apache Group/Apache/htdocs">」を「< ;Directory "C:/html">」に書き換える。 C同じように、「ScriptAlias……」の行も、「ScriptAlias /cgi-bin/ "C:/perl/cgi"」のように書き換え、ディレクトリ もこの場所に作る。 Dまた、忘れずに、「<Directory "C:/Program Fil es/Apache Group/Apache/cgi-bin">」を「& lt;Directory "C:/perl/cgi/">」に書き換えよう 。 Eこのフォルダ(c:\perl\cgi)に、「jcode.pl」を、必ず、入れ ておく。 起動と終了は、「スタート」からたどり、「ControlApacheServe r」から、startやstopが選択できる。startしても、何も起こらない? だーいじょうぶ。次の章に進もう。<Apacheの起動> AN HTTPDのほうも、設定の要点だけ書く。 @「ポート80」→「81」 A常駐アイコンを右クリック→「オプション・一般」→「一般」タブで開く設定ウィン ドの「拡張子 実行プログラム etc」の表から、「pl,cgi」を選択→「 編集」→「#!の行を調べる」にチェック。(これ絶対!) B「エイリアス」タブ→「仮想パス」欄の、「cgi-bin」は、Apacheで設 定したパスと同じにする。
<設定の様子> @により、Apacheと完全に共存できる。Aにより、jperlとperlを使 い分けられる。 起動と終了は、一般のWindows常駐ソフトと同じ感覚である。 動作確認 cgiの動作確認には、決まって、「hello」の文字を表示させることになって いる。だが、本当に、helloが見たいか?私は見たくない。 リスト1を、「c:\perl\cgi\」に、保存しよう。できれば、EUC+L Fで保存したほうがいいが、sjis+CRLFでも、きちんと動作した。 これは、おみくじCGIで、「大吉」が出るまで、自動リロードし続ける。毎朝これ を起動して、その日を「大吉」にしようという、人生ノウテンキなCGIである(笑) 。 といっても、必ず「大吉」では毎日占う意味がないので、色とりどりに結果の文字が 変わるなか、最後の「大吉」が赤文字だった場合こそ、ホントの大吉。しかも、一回の リロードもなく、いきなり赤い大吉に出会った、その日、あなたは、社長になれる!( と、mikuji.pl様が申しております)。 ぜひ、ブラウザのホームアドレスをmsnやgoogleから、この「おみくじスク リプト」に変えよう。 それにしても、これだけ遊び心のあるスクリプトで、たった14行。これが、Per l CGIの実力である(びっくりした?)。 起動方法は、ブラウザのURL欄に、「http://localhost/cgi -bin/mikuji.pl」と入力すればよい。次々リロードがかかり、「大吉」 が出て止まれば、Apacheのcgiは正常に動作している。 また、AN HTTPDの動作確認をするには、ブラウザのURL欄に、「http ://localhost:81/cgi-bin/mikuji.pl」と入力すれ ばよい。このように、Apacheと同じcgiを、AN HTTPDで起動するには 、localhostのあとに、「:81」を追加するのだ。
![]()
<mikuji.pl動作中 「:81」がある方は、AN HTTPDでの動作を示 している> デバッグと運用 EUCで編集できるテキスト・エディタは必須である。フリーウェアにもよいものが あるようだ。筆者はシェアウェアの「秀丸エディタ」が手に馴染む。 さて、入力したがうまく動作しなかった読者はいるだろうか?たった14行のスクリ プトである。しかし、一発で動作しなかった人も多いはずだ。そこで登場するのが、超 便利なバッチ・ファイル2種類。 p.bat C:\Perl\bin\perl %1 jp.bat C:\Perl\bin\MSWin32-x86-object\jperl.ex e %1 改行は入れないこと。各1行のシンプルなバッチ・ファイルだ。 このバッチ・ファイルをバカにしてはならない。よくある「;」の忘れとか、「"」 関連のバグなんかは、ブラウザで起動する前にこのバッチ・ファイルを使うことで、1 00%、駆逐できる。 さっそくテキスト・エディタで打ち込んで、「c:\perl\cgi」に放り込ん でおこう。 さらに準備は続く……。コマンド・プロンプト(またはDOSプロンプト)のショー トカットを作ろう。これに、「cgi-dir」という名称をつけ、プロパティの「作 業フォルダ」を「c:\perl\cgi」としよう。これで、クリック一発でcgi ディレクトリに降りられる。 さっそく、今のショートカットをダブル・クリックして、cgiディレクトリに降り た状態の、コマンド・プロンプトを起動する。ここで、「p mikuji.pl」と 打ち込んで、Enterすると、写真のように、syntax errorが表示され る。
<p.batでスクリプトをチェック> この場合は、line 9のエラーであるが、9行目がエラーである場合よりも、む しろ、直前の行で、対応するカッコが閉じていないような場合が多い。「スクリプト修 正」→「p.batのチェック」。プロンプトにHTML文字列が表示されるまで、こ の作業を繰り返す。 同じように、jperlスクリプトの場合は、「jp xxx.pl」Enterの ように使用する。「p.bat」「jp.bat」は、非常に簡単だが、同時に、目か らウロコの、ほとんど使われていない手法である。
こんな風に、デバッグはコマンド・プロンプトでやるのが、何しろいっとう速い。 しかし、パラメータを渡したいときもあるだろう。パラメータは、どうやって渡すの か?それを解決するのが、リスト2の方法である。 リスト2を、「c:\perl\cgi\」に、保存しよう。EUC+LFで保存す ること。 ブラウザから、「http://localhost/cgi-bin/test. pl?p1=2&p2=6」を表示させると、p1とp2というパラメータがcgiに 渡る。
<ブラウザ越しにパラメータを渡す> 同じように、コマンド・プロンプトから、「p test.pl "p1=64&p 2=flog"」を実行したのが、写真である。("記号は必須)。
<プロンプトからパラメータを渡す> このように、デバッグしたいスクリプトのパラメータ解釈の前に、「($ARGV[ 0]) && (($ENV{'QUERY_STRING'}) || ($ENV {'QUERY_STRING'} = $ARGV[0]));」と記述しておけば 、コマンド渡しの情報(変数)が存在し、なおかつ、「QUERY_STRING」が カラだった場合に限って、コマンドから「QUERY_STRING」に情報(変数) がコピーされる。 この方法で、大きなcgiを組むようなとき、さまざまな変数をコマンド・プロンプ トから入力して、デバッグを行なうことができる。 これも、目からウロコの、簡単なクセになかなか知られていない、とても便利な手法 である。 * 大急ぎでいろいろ見てきたが、本連載を見れば、Perl+CGIの自作道のとりこ になることを宣言しておく。そのためにも、perlとWebサーバのインストールに 、ぜひ、挑戦してみてほしい。 HP「今日からCGIプログラマー」(http://www.geocities. co.jp/SiliconValley-Cupertino/6103/) (辻豊史) ■リスト1 おみくじCGI(mikuji.pl) #! c:/perl/bin/perl require "./jcode.pl";srand;$c=(int(rand(5)));$ftr=(int(rand(10)));#占い @clr = ("#224962","#7794FF","#FF9900","#FF7D7D","#9FE765","#FF4949"); @res=("大凶","凶","末吉","小吉","小吉","中吉","中吉","吉","吉","大吉"); $line = "Content-type: text/html\n\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"><HTML><HEAD> <META http-equiv=Content-Type content=\"text/html; charset=x-sjis\"> <TITLE>みくじ</TITLE></HEAD><BODY><FONT size=+4 color=$clr[$c]> $res[$ftr] </FONT>";&lprint;# htmlヘッダと結果 if ($ftr <= 8) {$line = "……もう一回!パパンがパンッ! <META HTTP-EQUIV=\"refresh\" CONTENT=\"1.5;URL=$ENV{'SCRIPT_NAME'}\">"; &lprint;} #結果が思わしくない時は、もう一度占う print "</BODY></HTML>"; #終わり sub lprint {&jcode'convert(*line,sjis);print $line;} #サブルーチン ■リスト2 パラメータ実験(test.pl) #! C:\Perl\bin\perl.exe print "Content-type: text/html\n\n"; #---ブラウザのURL欄で渡すパラメータと、DOS窓のコマンドラインから与える #---パラメータを揃える、おまじない。二重カッコの位置に注意! ($ARGV[0]) && (($ENV{'QUERY_STRING'}) || ($ENV{'QUERY_STRING'} = $ARGV[0])); @get = split(/&/, $ENV{'QUERY_STRING'});#---パラメータ解釈 foreach (@get) { ($x ,$y) = split(/=/, $_);$qs{"$x"} = $y;} print "p1= $qs{p1}<BR>\np2= $qs{p2}<BR>\nARGV = $ARGV[0]";