CGIのHello World

第14回は、CGI(Common Gateway Interface)のHello Worldです。つまり、Webサーバ上に設置するCGIプログラムをさまざまな言語で記述して作成し、そのCGIにWebブラウザからアクセスすることによって、Webブラウザの画面に「Hello World」と表示することを目的とするものです。

シェルスクリプト(プレーンテキスト出力版)のCGI

まずはシェルスクリプトを使ってCGIを作成してみましょう。CGIは、基本的に出力データを標準出力に出力すればOKです。出力データには、最低限「Content-Type:」のヘッダを付ける必要があります。ヘッダとデータ本体の間には1行の空行が必要です。

CGIの出力がテキストデータの場合、その形式は、プレーンテキストか、またはHTMLになります。プレーンテキストの場合はリスト1のとおりです。Content-Type:には、text/plainを指定します。ヘッダや空行を含む複数行を1個のechoコマンドで出力するために、改行も含めた複数行をシングルクォートで囲んでいることに注目してください。

なお、このような複数行の出力には、「cat << 'EOF'」の形式のヒアドキュメントを用いることもできます。しかし、ヒアドキュメントでは、外部コマンドのcatが必要なことと、シェルの実装によってはヒアドキュメント部分のデータが一時ファイルとして作成されてしまうため、あまり美しくなく、echoコマンドとシングルクォートを使う方が簡潔でしょう。

リスト1 シェルスクリプト(プレーンテキスト出力版)のCGI(cgi_sh_text.cgi)

シェルスクリプト(HTML出力版)のCGI

HTMLを出力するCGIはリスト2のとおりです。こちらではContent-Type:をtext/htmlとし、データ本体はHTMLのタグを使って記述します。ヘッダ、空行、HTMLデータを含めた全体をシングルクォートで囲み、それを1個のechoコマンドで出力している点は前項のプレーンテキスト出力版と同じです。

リスト2 シェルスクリプト(HTML出力版)のCGI(cgi_sh_html.cgi)

CGIの実行方法

作成したCGIを動作させるには、CGIスクリプトに「chmod +x」で実行属性を付けるだけでなく、そのCGIファイルがCGIであることをWebサーバに認識させる設定を行う必要があります(これを忘れると、Webアクセス時にCGIが実行されず、CGIのスクリプトそのものがWebブラウザに表示されたりします)。

この設定は、Webサーバのシステム側で行う方法と、ユーザ側で行う方法がありますが、ユーザ側で行うには、リスト3のような「.htaccess」という名前のファイルを、CGIのファイルと同じディレクトリに配置しておけばOKです。なお、この例では拡張子「.cgi」のファイルをCGIとみなすという設定になっています。

リスト3 .htaccess

以上の準備が完了したら、CGIにWebブラウザからアクセスしてみましょう。すると、図1のように表示されるはずです。これはHTML出力版での表示ですが、プレーンテキスト出力版でも同様です。

図1 cgi_sh_html.cgiにFirefoxでアクセスしたところ

awkを使ったCGI

前述のHTML版のCGIを、awkを使って書くとリスト4のようになります。どの言語を使う場合でも、CGIとして出力するべき文字列は同じで、結局、複数行の文字列をなるべく読みやすい形で記述するという問題に帰着されます。

awkでは、複数の文字列を「"abc" "def"」のように単純に(カンマなしで)並べると、それらは連結されて"abcdef"というひとつの文字列とみなされます。そこで、文字列を1行ごとにダブルクォートで囲むのが見やすいでしょう。ただし、print文や、ダブルクォートとダブルクォートの間で改行するために、バッククォート「\」は必要です。また、各文字列の行末には改行コードの\nを記述する必要があります(ただし最終行については、print文によって改行コードが付加されるため、\nは不要です)。

リスト4 awkを使ったCGI(cgi_awk_html.cgi)

Perlを使ったCGI

Perlでは、特殊ファイルハンドルのDATAを使い、__DATA__トークン以降に文字列を直接記述する方法がわかりやすいでしょう(リスト5)。この方式では、文字列部分をクォートする必要がありません。これ以外の方法としては、シェルスクリプトの場合と同様に、文字列全体をシングルクォートで囲む方法も考えられます。

リスト5 Perlを使ったCGI(cgi_perl_html.cgi)

Pythonを使ったCGI

Pythonでは、複数行をまとめてクォートできるトリプルクォート(シングルクォートまたはダブルクォートを3個重ねたもの)を使うのが便利です(リスト6)。このように、文字列全体を1回のprintで出力します。

リスト6 Pythonを使ったCGI(cgi_python_html.cgi)

Rubyを使ったCGI

Rubyには、Perlの__DATA__に相当する記法がないため、シェルスクリプトの場合と同様に、複数行の文字列をシングルクォートで囲む方式がよいでしょう(リスト7)。

リスト7 Rubyを使ったCGI(cgi_ruby_html.cgi)

Tclを使ったCGI

リスト8は、Tcl/Tkのスクリプト部分であるTclを使ったCGIです。実際にTclでCGIを作る可能性は少ないと思われますが、あえて記述すると、このようになるでしょう。複数行の文字列は、{ }で囲めば、改行も含めてそのままの文字列として解釈されるため、これをputsで出力すれば完了です。

リスト8 Tclを使ったCGI(cgi_tcl_html.cgi)

C言語を使ったCGI

C言語では、awkの場合と同様に、ダブルクォートで囲まれた複数の文字列をカンマなしで単純に並べると、コンパイル時にひとつの文字列に連結されて解釈されます。さらに、awkとは違って、連結される2つの文字列の間で、ソース記述上で改行する場合に、バッククォートは必要ありません。よって、リスト9のように記述すればOKです。なお、当然ながら、C言語(および次項のC++)のCGIを使用する際には、Webサーバと同じOS上でコンパイルする必要があります。

リスト9 C言語を使ったCGI(cgi_c_html.cgi.c)

C++を使ったCGI

C++を使う場合はリスト10のようになります。ここでも、C言語と同様に、ダブルクォートで囲んだ複数の文字列を並べて連結させる方法をとっています。なお、C++では改行としてendlが使えますが、この場合はendlを使わずに文字列の中に\nを記述した方がわかりやすいでしょう。

リスト10 C++を使ったCGI(cgi_cpp_html.cgi.cc)