CGI
メインページ > 工学 > 情報技術 > プログラミング > CGI
CGI(シージーアイ、Common Gateway Interface)とは、ウェブサーバが独立した外部プロセス(CGIプログラム)でウェブページを生成できるようにする仕組みです。CGIプログラムの記述にはPerlなどのスクリプト言語がよく用いられますが、基本的に標準入出力を備えているプログラミング言語であれば(たとえばC言語やシェルスクリプトでも)用いることができます。
概要

ウェブサーバのApacheは、PHP・Perl・PythonやRubyのようなスクリプティング言語のコードだけでなく、C言語をコンパイルしたバイナリファイルも実行できます(ただし、バイナリなので、ホストアーキテクチャごとにコンパイルしなおす必要があり、取り回しが悪いので、例外的に処理速度が極端に必要な場合以外には、めったにC言語によるバイナリをCGIに使用することはありません)。
概要

広い意味での『CGI』の「プログラミング言語の内容を実行する」との意味は、具体的にはウェブページでユーザからの入力に応答したり、動的な出力を行ったりするための機構などもCGIです。CGIの規格はhttp://hoohoo.ncsa.uiuc.edu/cgi/interface.html(インターネットアーカイブ: https://web.archive.org/web/20070809114039/hoohoo.ncsa.uiuc.edu/cgi/interface.html )で定められています。ここで動的とはたとえば、ブラウザからリクエストを受け付けた日時をページとして表示させるものも動的なページの一つです。ウィキやブログなども動的なページに含まれます。これに対して静的とはあらかじめ用意してあるHTML等で記述されたドキュメントをリクエストへの応答時に変更を行わずに配信することを指しています。
概要

PerlやPHPなど用いている言語が何かかは別として、現在インターネット上で大規模、あるいは著名なウェブサイトのほとんどは何らかの動的な仕組みを有していると考えられます。CGIの仕組みを理解することは大規模なデータをインターネット上で出版する技術的な背景を学ぶのと強い関係があると言えます。
概要

動的なウェブアプリケーションの実装技術は、CGI以外にも mod_perl のようなApache向けのモジュールや FastCGI のような外部の常駐プロセスとの連携技術があります。 これらのCGI以外の方法が用いられるのは、CGIには「外部プロセスをリクエストがあるごとに起動しなければいけない」という欠点があり、プロセスの起動は毎秒数百から数千が限度で、この数は比較的小規模のウェブサイトでも容易に達する数です。このことからCGIでリクエスト毎にプロセスを起動するのではなく、動的コンテンツをモジュールや常駐プロセスに生成するのが現在の主流です。 このウィキブックスをサービスしているMediaWikiもPHPの常駐プロセスで実装されています。
概要

CGIが行う動的な作用は主に以下の4要素によって成り立っています。
概要

ウェブサーバで動的にコンテンツを生成する仕組みには他に、ウェブサーバのモジュール(mod_perlなど)やFastCGIがあります。 これらのCGIと大きな違いは、CGIの「リクエストごとに新しくプロセスを生成する」という負荷の大きな処理を、ウェブサーバプロセス内で実行したり、常駐するプロセスとウェブサーバの間での通信を行うことで避けている点です。
C言語でCGI

ApacheはCGIを実行するためには htttpd.conf の書換えの必要があります。
C言語でCGI

XAMPPであれば、場所は、\xampp\apache\conf の中に設定ファイル
C言語でCGI

があるので、探して httpd.conf のファイルの中身の下記のような部分を、下記のように書換えます。
C言語でCGI

多くのGNU/Linuxのディストリビューションでは、 /etc/httpd/conf に httpd.conf があります。 /etc/httpd.conf の所有者は root もしくは www なので、sudo vi /etc/httpd.conf などとし書込み保護した状態を維持してください。
C言語でCGI

設定の方法は2種類あります。
C言語でCGI

書き換え前
C言語でCGI

書き換え後
C言語でCGI

ScriptAlias という行を、下記のようになるように、書き換えます。
C言語でCGI

どちらの方法で編集するにしても、もしApacheをすでに立ち上げていたら、いったんApacheを終了してから、再度、立ち上げ直して下さい。
C言語でCGI

Apacheの起動時に設定ファイルを読み込む方式のようなので、立ち上げ直さないと、設定が反映されない場合があります。
C言語でCGI

Apacheを終了させるには、コマンド
C言語でCGI

でApacheが終了します。
C言語でCGI

右上のXボタンを押してコマンドラインなどのウィンドウを閉じるだけでは、Apacheが終了しない場合が普通なので、終了させるためにはコマンド入力で確実に、いったんApacheを終了させてください。
C言語でCGI

Apacheを立ち上げるには、コマンド
C言語でCGI

で立ち上がります。
C言語でCGI

今後の作業の暗黙の前提として、Apacheサーバーを立ち上げるのを忘れないように(よく忘れてエラーになります)。さっさと先にApacheサーバを立ち上げましょう。
C言語でCGI

さて、たとえば、下記のようなC言語ファイルをテキストファイル(『メモ帳』で良い)に書いて、コンパイル(gccでも良い)して、実行ファイル(windowsならexeファイル)にしましょう。
C言語でCGI

コード例
C言語でCGI

Content-Type: text/html というのは、Apache側が解釈のために必要な情報であり、これから送られてくるprintf文の内容が、テキストファイルまたはHTMLファイルであることを宣言しているテキスト文です。「HTMLヘッダー」などと言われます、webでの情報のやりとりをする際の、送受信メッセージ文の一種です。
C言語でCGI

さて、Windows版ApacheであるXAMPPの場合、上記コード例をコンパイルして出来上がった実行ファイル(ファイル名を指定しなければWindows版gccなら「 a.exe 」という名前になります)を、 フォルダ \xampp\cgi-bin に入れればいいです。
C言語でCGI

GNU/Linux版の素のApacheの場合、フォルダ cgi-bin の場所は
C言語でCGI

ですので、そこにa.outなどの実行ファイルをいれればすみます。ですが、初期設定では、root所有になってますので、chownコマンドで所有者を変えてください。
C言語でCGI

とにかく、cgi-bin フォルダにバイナリファイルを入れたら、のあと単にウェブ・ブラウザーで
C言語でCGI

にアクセスすればいいです。
C言語でCGI

または実行ファイル名がa.exe以外の別のファイル名なら、
C言語でCGI

にアクセスすればいいです。
C言語でCGI

すると、
C言語でCGI

上記コードの場合
C言語でCGI

というふうに、webページでprintf文の内容が表示されます。(GNU/Linux版Apacheでも同様の結果です。Fedora 32 で2020年7月14日に確認。)
C言語でCGI

C言語バイナリだろうが、Apache側がHTMLファイルを解釈してくれるので、なので、下記のようにprintf文中にHTMLタグを書いてバイナリ化しておけば、自動的にApacheがうまく変換して、ブラウザにHTMLタグの指示通りに表示できるようにしてくれます。
C言語でCGI

コード例
C言語でCGI

上記コードをコンパイルしたバイナリファイルをフォルダ cgi-bin に入れたあと、ウェブ・ブラウザーでアクセスすると、大きな文字で、
C言語でCGI

と表示されます。 (GNU/Linuxでも同様の結果です。Fedora 32 で2020年7月14日に確認。)
CGIそのものの実装方法

もし、興味あるのがCGIを使ったサーバ公開ではなく、CGIそのものの機能を作りたい場合、そのためのCGIの原理の知識は色々と考えられますが、OSのコマンドラインに搭載されている
CGIそのものの実装方法

が、原理的と思われる方法です。(なお、理解のために方法を紹介しているだけであり、通常のサーバ構築ではCGI機能自体の新規の実装は不要な作業です。すでにApacheなどの既存のサーバソフトにCGI機能が搭載されているからです。)
CGIそのものの実装方法

また、コマンドプロンプトに実行させたいコマンド列をテキストファイルに記述して繰り返し使うことが出来ます。 Windowsならバッチファイル、UnixまたはUnixに類したOSならばシェルスクリプトと呼ばれます。
CGIそのものの実装方法

本科目では、リダイレクトについて説明します。バッチファイルの解説は別の科目にゆだねます(たとえば『DOS入門』などを参照してください)。
CGIそのものの実装方法

リダイレクトについては、Windowsの場合、コマンドプロンプトで
CGIそのものの実装方法

と入力すれば、標準出力に出される文字列がそのまま、リダイレクト先のファイルに書き込まれて保存されます。
CGIそのものの実装方法

たとえば実行ファイル名「hello.exe」で、リダイレクト先ファイル名「ridtest.txt」なら
CGIそのものの実装方法

というコマンドになります。
CGIそのものの実装方法

間の演算子の機能は
CGIそのものの実装方法

になります。
CGIそのものの実装方法

CGI用のウェブサーバーにおいて、CGIプログラムの出力を処理する方法は複数あります。一般的には、指定されたCGI用のフォルダ内にある実行ファイルをリダイレクトして実行することで、その出力をテキストファイルとして扱うことができます。ただし、この方法は現代の実装ではあまり使用されていません。
CGIそのものの実装方法

実際の現場では、より効率的な方法が一般的に採用されています。例えば、Apacheや他のウェブサーバーでは、CGIプログラムの出力を直接パイプラインに渡し、他のプログラムや処理と連携させることができます。この場合、リダイレクトや一時ファイルの作成を回避し、データの処理を効率的に行うことができます。
CGIそのものの実装方法

パイプラインを使用することで、CGIプログラムの出力を別のプログラムや処理に直接渡すことができます。これにより、リアルタイムのデータ処理や複雑なデータフローを実現することができます。また、パイプラインを使用することで、複数のプログラムを連鎖させてデータを処理することも可能です。
CGIそのものの実装方法

実行ファイルがカレント・ディレクトリにある場合、
CGIそのものの実装方法

ストリームを指定したリダイレクトのためのコマンドの書式は、
CGIそのものの実装方法

です。これで、リダイレクト先ファイルに、書き込まれます。 この書式は、sh ksh bash zsh に共通ですが csh とは異なります。
CGIそのものの実装方法

たとえば実行ファイル名 hello で、リダイレクト先ファイル名が text.txt なら
CGIそのものの実装方法

というコマンドになります。
CGIそのものの実装方法

なお、ストリーム番号の意味は
CGIそのものの実装方法

になります。
開発の参考

Perl/CGI のページも見てください。 Perl/ライブラリ・モジュールとオブジェクト指向 のページもご覧ください。
開発の参考

テキストエディタ TeraPad(テラパッド)等のテキスト(拡張子 *.txt)を *.cgi に変えた物です。書かれている内容はtextなのでコード指定はテキストエディタのファイルオープンでUTF-8に変えてから日本語が使えます。変えないと文字化けします。
開発の参考

動作が確認され ミスがないのが確認されたら、契約サーバーにアップロードをFFFTP等でおこないます。皆さんに楽しんでもらいましょう。属性(パーミッション)の変更もお忘れなく。
開発の参考

Perl/制御構造・Perl/リファレンス・Perl/はじめに もご覧ください。
開発の参考

w:とほほのWWW入門は、良い情報源になるかもしれません。
開発の参考

本書ではApache HTTP Serverを用いた例を示しますが、ほかにも多くのウェブサーバでCGIが利用可能です。
Apache HTTP Server 2.2の組込み

PHPやPerlとは関係なく、一般に Apache の起動の方法は、GNU/Linux(Fedora32)の場合、ターミナル画面で、コマンド
Apache HTTP Server 2.2の組込み

です。(CentOS 7 以降はこうのようです。)
Apache HTTP Server 2.2の組込み

httpd とはlinuxの場合、Apache のことです。
Apache HTTP Server 2.2の組込み

なお、昔は
Apache HTTP Server 2.2の組込み

というコマンドのようでした。
Apache HTTP Server 2.2の組込み

Apache が正常に動いているか確かめるには、ブラウザを開き、アドレスバーに
Apache HTTP Server 2.2の組込み

http://localhost
Apache HTTP Server 2.2の組込み

と入力します。
Apache HTTP Server 2.2の組込み

バージョンにもよりますが、Apacheのロゴマークの羽の絵のあるwebページが表示されていれば、たぶんインストール成功しているでしょう。
Apache HTTP Server 2.2の組込み

Apache を終了するには、GNU/Linuxならターミナル端末で
Apache HTTP Server 2.2の組込み

で終了します。
Apache HTTP Server 2.2の組込み

昔は
Apache HTTP Server 2.2の組込み

で終了でした。
Apache HTTP Server 2.2の組込み

終了後に先程の localhost のリンク先に移動しても、何も読み込みできないハズです。(Apacheを終了したので、読み込みできないのが成功。) そもそもアパッチをどうインストールすればいいかについては、たとえば『PHP/確実に動作させるまで』などに解説があります。(2020年4月21日の時点では、まだ Apache 専用のページはWikibooks日本語版にはありません)。
Apache HTTP Server 2.2の組込み

GNU/Linux の CentOS系の場合、フォルダ階層 var/www/html に、目的のhtmlファイルを入れます。(なお、このようなフォルダ(そこにhtmlなどを入れるとサーバーが公開してくれる場所)のことをドキュメントルート DocumentRoot という。)
Apache HTTP Server 2.2の組込み

あらかじめ、目的のhtmlファイルを作っておく。
Apache HTTP Server 2.2の組込み

たとえば、serverTest.html というファイルが作ってあり、このhtmlファイルを公開したい場合、
Apache HTTP Server 2.2の組込み

まず、
Apache HTTP Server 2.2の組込み

というコマンドになります。
Apache HTTP Server 2.2の組込み

SE Linux がオンだと設定が面倒なので、
Apache HTTP Server 2.2の組込み

でSE Linuxをオフできます。
Apache HTTP Server 2.2の組込み

ウェブ・ブラウザーで http://localhost/serverTest.html にアクセスして、作成したhtmlどおりの内容が表示されれば、ここまでは成功。(外部公開するには、まだ作業が続く。)
Apache HTTP Server 2.2の組込み

ファイル名の部分(例では末尾の serverTest.html )は、作成したhtmlファイルのファイル名にします。
Apache HTTP Server 2.2の組込み

ウェブ・ブラウザーで確認し終わったら
Apache HTTP Server 2.2の組込み

でSElinuxの設定をオンに戻す。
Perl/CGIプログラムの例

PerlでCGIプログラムをする場合、
Perl/CGIプログラムの例

perlだけでなく perl-CGI もインストールする必要があります。
Perl/CGIプログラムの例

GNU/Linux の Fedoraの場合、
Perl/CGIプログラムの例

で両方とも入ります。sudo dnf install perl だけでは、perl-CGI がインストールされません。
Perl/CGIプログラムの例

Fedoraにインストールする場合、dnf コマンドでの perl-CGIの末尾3文字の「CGI」は大文字でなければなりません(でないとパッケージマネージャーが認識しません)。
Perl/CGIプログラムの例

下記のコードは、Perlによる単純なCGIプログラムの例です。CGIプログラムは、後述の設定をしたあとにウェブ・ブラウザーで閲覧して確認できます。(コマンド端末では確認できないか、著しく確認が困難。)
Perl/CGIプログラムの例

text/htmlのあとのエスケープシーケンスは必ず2つ \n\n としてください。もし1つだけだと、ブラウザで見てもエラーになり、「Hello World!」が表示されません。(もし \n が 1つだけだと「500 Internal Server Error」になります。)
Perl/CGIプログラムの例

というのは何かというと、これはshebangというOSの機能で、インタプリタに何を使うかを指定します。
Perl/CGIプログラムの例

書式はコメント文と同様に「#」から始まり形式的にはコメントですが、コメントではないので消さないでください。消すと動作しなくなります(例えば、bash のプロンプトから実行すると bash スクリプトとして perl スクリプトを実行してしまいます。おそらく bash の構文ではないのでエラーになります)。
Perl/CGIプログラムの例

PerlだけでなくUnix系のシェルスクリプトなど他のプログラム言語でも同様にshebangを記述する事があります。
Perl/CGIプログラムの例

は、HTTPレスポンス・ヘッダーの一部で、ウェブ・ブラウザーなどユーザー・エージェントは、HTML本体とは別に、受信しようとする情報の種類などの打合わせのために HTTPヘッダーを送受信しあってます(Perlの場合は「CGIヘッダー」ともいい「HTTPレスポンス・ヘッダー」と区別していますが、Webサーバがヘッダー要素を追加する可能性がある為です)。
Perl/CGIプログラムの例

そのHTTPレスポンス・ヘッダーで送受信しあう情報のひとつに「Content-Type: 」ヘッダーがあります。「Content-Type: text/html」というヘッダーによって「これからテキストの1つであるHTMLを送る」と相手先に伝えています。
Perl/CGIプログラムの例

HTMLのソースコードを送りたい場合は、下記のように書きます。
Perl/CGIプログラムの例

しかし実用的には、下記のようにプログラムを書いたほうがラクでしょう。
Perl/CGIプログラムの例

use warnings; とは何かというと、これはプログラム中にエラーがあったら警告を出すという意味です。Perlはプログラム言語ですので、エラーも起こりえます。そのエラーの際に警告を出すという意味です。
Perl/CGIプログラムの例

ですが、これはコマンド端末で実行している場合のハナシです。
Perl/CGIプログラムの例

ウェブ・ブラウザーで見ている場合、そのような気のきいた警告はしてくれません。
Perl/CGIプログラムの例

また、use warnings; は警告をするだけですので、そのままプログラムを実行します。けっして、気をきかしてプログラム停止したりはしません。
Perl/CGIプログラムの例

use strict; は、プログラムの停止なども含めて、より厳格に判定および処置をします。
Perl/CGIプログラムの例

なので、上記プログラムから use warnings; および use strict; を除去しても、ウェブ・ブラウザー上で表示する事は可能です。
Perl/CGIプログラムの例

このファイルは、拡張子をかならず「.cgi」にしてください。(拡張子「.cgi」または「.pl」にしないと、今後の設定が面倒になります。)
Perl/CGIプログラムの例

このファイルを、フォルダ階層
Perl/CGIプログラムの例

の中に配置します。
Perl/CGIプログラムの例

もし cgi-bin フォルダがまだ作れていない場合、perl-CGIがまだインストールされてないと思われるので、まずperl-CGIをインストールしてください。
Perl/CGIプログラムの例

所有者がrootになってるなどで、配置できないなら
Perl/CGIプログラムの例

で所有者を変更できます。
Perl/CGIプログラムの例

冒頭の
Perl/CGIプログラムの例

の部分は、環境によっては
Perl/CGIプログラムの例

の場合もあります。
Perl/CGIプログラムの例

この部分 #!/usr/local/bin/perl は、perlのインタプリタを呼出してスクリプトを渡すための指示です。
Perl/CGIプログラムの例

これらperlインタプリタのバイナリの存在場所をさがすには、コマンド
Perl/CGIプログラムの例

で探せます。
Perl/CGIプログラムの例

そして、制作したサンプルファイルは、アクセス権の設定で「プログラムとして実行可能」にチェックボックスを入れてください。右クリックで現れるダイアログから設定できると思います。
Perl/CGIプログラムの例

インタープリターへのパスがわからない場合は、あるいは色々な環境で動かすことが想定される場合(本書もそのケースです)
Perl/CGIプログラムの例

の様に POSIX でパスが決まっている env(1) を呼出し、(絶対パスでなく)コマンド名でインタープリターを指定します。 こうすると、env は環境変数PATHの中から順に インタープリター を探し、見つかったインタープリターにスクリプトを渡し起動します。
Perl/CGIプログラムの例

しかし、サーバがApacheの場合、まです、これだけでは動きません。
Perl/CGIプログラムの例

Apacheは初期設定では、cgiスクリプトを動かさない設定になっています。なので、まず、この初期設定を書き換える必要があります。
Perl/CGIプログラムの例

cgiスクリプトを動かせるように設定を変更するために、設定ファイルの httpd.conf というファイルを書き換えて、
Perl/CGIプログラムの例

という文章を追加する必要があります。
Perl/CGIプログラムの例

なお、通常のapacheでは、すでにコメントアウトされた状態で
Perl/CGIプログラムの例

とあるので、単に冒頭のコメントアウト記号#をはずせばいいだけです。
Perl/CGIプログラムの例

この書き換えにより、拡張子 .cgi のあるファイルを、cgiスクリプトとして処理できるようになります。
Perl/CGIプログラムの例

なお、perlなどで使われる拡張子 「.pl」のファイルもCGIスクリプトとして実行したいなら、上記の AddHandler に
Perl/CGIプログラムの例

と「.pl」を追加するだけで済みます。
Perl/CGIプログラムの例

ただし、管理者が通常では root になっているので、そのままでは、書き換えできません。なのでGNU/Linuxの場合、コマンドで
Perl/CGIプログラムの例

で、管理者を変えてから、管理者設定を書き換えることになります。
Perl/CGIプログラムの例

書き換えが終わったら、apache を立ち上げ直します。
Perl/CGIプログラムの例

そして、ウェブ・ブラウザーで
Perl/CGIプログラムの例

にアクセスしてください。
Perl/CGIプログラムの例

ブラウザ画面上に
Perl/CGIプログラムの例

と表示されています。また、そのページのタイトルとして、タブ欄などに「Example Web Page」と書いてあります。
Perl/CGIプログラムの例

では、より実用的なプログラムを見ていきましょう。
Perl/CGIプログラムの例

下記のプログラムは、入力した文字列を、htmlのフォーム機能を使って別ファイル(例では catchtest.cgi ) に送るプログラムです。
Perl/CGIプログラムの例

※ 『PHP/HTMLフォームからのデータ受け取り』と動作内容は同じです。
Perl/CGIプログラムの例

このように、パターンとして
Perl/CGIプログラムの例

というような書式で、単に <!DOCTYPE html> と EOT のあいだに、お決まりのパターンのコードを書くだけで、入出力機能のあるファームも簡単に作れます。
Perl/CGIプログラムの例

上記のコードの遷移先のページは、下記のようにつくります
Perl/CGIプログラムの例

たとえば ggggggg とブラウザに表示された入力ボックスにしてボタン「登録」を押すと、
Perl/CGIプログラムの例

と表示されます。
Perl/CGIプログラムの例

まず、遷移先のページにも、shebangやHTTPレスポンス・ヘッダーを忘れないようにしましょう(無いとエラーになります(Internal Server Error など) )。
Perl/CGIプログラムの例

上記コードの if文 と else文 は、決まり文句です。 $msg以外はすべて、Perlでの決まり文句です。STDINは標準入力のことです。
Perl/CGIプログラムの例

Perlでは、formタグからのPOSTの受け取りは、標準入力 STDIN を通して受け取りが行われる仕様です。
Perl/CGIプログラムの例

環境変数として REQUEST_METHOD や CONTENT_LENGTH や QUERY_STRING という環境変数があらかじめ用意されています。なので上記コードでは、この変数はこのまま使う必要があります(勝手に名前を変えてはイケナイ)。
Perl/CGIプログラムの例

なお、環境変数を英語で environmental variable と言います。
Perl/CGIプログラムの例

というのは、おおむね「もし環境変数 REQUEST_METHOD が POST なら」 のような意味です。
Perl/CGIプログラムの例

環境変数 REQUEST_METHOD には、フォームを呼び出した時のリクエストの結果がPOSTまたはGETのどちらかとして入っています。
Perl/CGIプログラムの例

eq 演算子は、「eqの左右の両辺をもし文字列とした場合に、両辺が等しいか?」を調べる演算子です。
Perl/CGIプログラムの例

いっぽう、== 演算子は、両辺を数値とした場合に等しいかを調べる演算子です。(C言語と違って、Perlでは変数の宣言時に型指定が無いので、条件分岐if文では、こういった演算子の区別が必要になります。)
Perl/CGIプログラムの例

なので、けっして eq演算子の部分を == 演算子に変えてはダメです。
Perl/CGIプログラムの例

なお、両辺が等しくない場合については、文字として評価する場合には ne 演算子、数値として評価する場合には != 演算子 です。
Perl/CGIプログラムの例

さて、表示結果の username というのは単に、勝手につけたオブジェクト名であり、呼び出し元のファイルのHTMLタグで勝手に命名したオブジェクト名ですので、もしそのオブジェクト名が変われば、表示結果の左辺のこの部分は名前になります。
Perl/CGIプログラムの例

結局
Perl/CGIプログラムの例

のように、オブジェクト名と一緒に、Perlでは POST で受け取った内容を管理する仕組みです。
Perl/CGIプログラムの例

より高度なCGIプログラムは次のようになります。
Perl/CGIプログラムの例

上記の書き方は「信じられない植物 ダウンロード」で検索して、参考に見てください。CGIのゲームです。
Perl/CGIプログラムの例

ちょっと古い見なれた構文 オリジナルです。printは一般的に使われています。