
いつも助け手いただいており,ありがとうございます。
ある団体のお手伝いでHPをいじっております。
基本,既製のスクリプトを改造しながら,あれこれやっておりますが,
新たに作る必要がうまれ,あれこれ始めましたが,open にてつまづきました。
perlについては,初心者のレベルだと思います。
やってることは単純なことだと思うのですが,下記内容のhtmlファイルを開くことです。
ファイル名 test.html
中身↓
<!DOCTYPE html>
<html>
<head>
<title>ページタイトル</title>
</head>
<body>
<p>うまく動くでしょうか。</p>
</body>
</html>
このファイルを開くのに,
ファイル名 app.cgi
中身↓
#!/usr/bin/perl
open (IN,"test.html"); #index.htmlというHTMLファイルを読み込む
my @tmp=<IN>;
close (IN); #ファイルハンドルを閉じる
print @tmp;
exit;
だと500のサーバーエラーになりますが,下記のようにprint(・・・・)を入れるときちんと実行できます。
ファイル名 app.cgi
中身↓
#!/usr/bin/perl
print "Content-type: text/html\n\n";
open (IN,"test.html"); #index.htmlというHTMLファイルを読み込む
my @tmp=<IN>;
close (IN); #ファイルハンドルを閉じる
print @tmp;
exit;
なぜprintを入れるとエラーにならないのか分かりません。テキストファイルを開くときは,
printを入れなくてもひらけるようですが,この辺の違いがよく分かりません。
アドバイスいただけるとありがたいです。
No.5ベストアンサー
- 回答日時:
普段意識することはありませんが。
htmlファイルに書いたものがそのまま送信されているのではありません。
リクエストを送ると、受け取ったサーバーは URLを解釈してデータを送り返してきます。
このとき送られてくるデータには「ヘッダー」が付けられます。
ヘッダーはテキストで書かれた情報であり、改行だけの行で本体データと区切られます。
例えば
http://〜/test.html
とブラウザに入力したら、受けとったサーバーは
該当するファイルを読み込み、ヘッダーを付けて
Content-type: text/html
(その他のヘッダー)
(改行だけの行)
<!DOCTYPE html>
(以下test.htmlの内容)
というデータにして送り返します。
受けとったブラウザはヘッダーと本体データを分けて処理します。
例) Content-type: text/html はHTMLファイルなので、本体データをHTMLと解釈してブラウザで表示する。
CGIというのは、このHTTPサーバーの
「該当するファイルを読み込み、ヘッダーを付けて送信」
という動作のかわりに
「該当するプログラムを実行し、出力をそのまま送信」
という動作をするものです。ファイルのときにあった「ヘッダーを付けて」の部分はプログラムに組込まれています。
ヘッダーが不正なものはエラーになります。
print "Content-type: text/html\n\n";
はこのヘッダーを出力するものです。
削除すると全体として「不正なデータを出力するプログラム」になってしまうためにエラーになります。
openとは関連はありません。
なお、そのプログラムは「該当するファイルを読み込み、ヘッダーを付けて送信」というのをCGIで書いたものです。
詳しい解説ありがとうございます。
print "Content-type: text/html\n\n";
がないと,「不正なデータを出力するプログラムになる」
ということ理解できました。
ただ,open には関係ないとのことですが,
読み込んだデータを出力する print と close を逆にすると,エラーがでなくります。
このあたりは,どう,解釈すればいいのでしょうか。
それほど多くのものためしたのではないのですが,少なくとも,正常に表示されている,html ファイルを,2,3,読み込んでみましたが,読み込みに使った,質問に掲載したスクリプトでは,print部分なしでは,エラーになります。
ということは,正常に表示されているファイルは,表示に使っているスクリプトのどこかで,
"Content-type: text/html\n\n";
を記述して,送信しているのでしょうか
それから,気になる部分ですが,冒頭に,
http://〜/test.html
とあります。今回質問に掲載させていただいたのは,
http://〜/app.cgi
とcgiを呼び出しています。
この辺も,関係あるのでしょうか。
アドバイスいただければありがたいです。
No.4
- 回答日時:
こんにちは
横からですが・・
No3様が指摘していらっしゃる「ヘッダー」に関して、少し調べてみるのが宜しいかと思います。
https://allabout.co.jp/gm/gc/433673/2/
http://sak.cool.coocan.jp/w_sak3/doc/sysbrd/pe_k …
早速のご回答ありがとうございます。
私も,エラーの原因は,ヘッダー がらみかなとは推測していたのですが,
質問に掲載した,表示使用としているhtmlファイルにも最低限の情報は書かれているように思うのですが。
No2 さんの解答のように,close と 最後の print を逆にすると,
最初の print が無くてもエラーになりません。
この辺が,どうしてなのか,という疑問が残ります。
No.3
- 回答日時:
No.1です。
> print の記述のある説明をみていませんでした。
print文は指定された内容を標準出力するだけです。
そうではく
> print "Content-type: text/html\n\n";
は具体的に何を書き出しているかです。
試しに
print "Content-type: text/html\n";
としてみましょう。\n\nではなく、\nとしてみるのです。
どうなりますか?
このprint文で出力しているのはHTTPヘッダーのうちのContent-type行です。
では、test.htmlファイルの中身は何でしょう?
そういう最も基本的なHTTPのデータ構造を理解していないので「このprint文の有無で何でエラーになったりならなかったりするの?」となるのでしょう。
プログラムの表面ばかり見ていて、プログラムが動く環境とプログラムが何をしていいるかを理解していないから起きている問題だと当方は思います。
ではでは。
何度もアドバイスありがとうございます。
繰り返し,になりますが,質問するにあたって,
test.html
の内容も最初の質問に記載しておりますので,test.html中身は何でしょうと聞かれても,返答にこまるのですが。
私としては,test.htmlの中身も理解した上での質問だと思っております。
付け加えると,単なるテキストファイルだとエラーになりません。
この辺も含めてアドバイスをいただけるとありがたいです。
No.2
- 回答日時:
おそらく、
close (IN); と
print @tmp; の順番が逆なんだと思うが、
print "Content-type: text/html\n\n"; を書き足すと
なぜエラーにならないのかは、サッパリ解らない。
早速の解答ありがとうございます。アドバイの通り,
直して,確かめてみました。
#!/usr/bin/perl
open (IN,"test.html");
my @tmp=<IN>;
print @tmp;
close (IN); #ファイルハンドルを閉じる
exit;
で,実行してみましたら,エラーはでませんでした。
close (IN); はファイルハンドルを閉じるだけなので,その後でprintしても,配列にとりこまれた@tmpの内容は保持されると思ってましたが,違うんでしょうかね。
>print "Content-type: text/html\n\n"; を書き足すと
>なぜエラーにならないのかは、サッパリ解らない。
の理由を知りたいと思っての投稿です。
openの前のprintがなくても,
テキストファイルのopenだと,close の後にprintしてもエラーにならないようです。
No.1
- 回答日時:
> このファイルを開くのに,
>ファイル名 app.cgi
> 中身↓
えっと。。。
この文章の意味をり合い出来ません。
> #!/usr/bin/perl
これはPerlで記述するCGIプログラムの頭に記すPerlの実行プログラムが置かれている場所です。
> open (IN,"test.html"); #index.htmlというHTMLファイルを読み込む
実際にオープンしようとしているファイル名(test.html)とコメントにあるファイル名(index.html)が一致していません。
細かい事ですが。。。
また、やっていることは「index.htmlというHTMLファイルを読み込む」ではなく「test.htmlファイルのオープン」です。
更に言えば、ファイルのオープンをしていることはプログラムソースを見ればわかるので、コメントして必要なのはtest.htmlはどういうファイルなのかの説明です。
> だと500のサーバーエラーになりますが,
HTTPの500番のエラーの意味は確認されましたか?
これはWebサーバー上でのCGIプログラムの実行で何らかのエラーが発生したため、実行中のCGIプログラムの処理を打ち切った・・・つまりこれ以上このCGIプログラムを実行することが出来なくなったというものです。
で、ですね。。。
質問者様はご自身が扱っているプログラムが何をしているかを理解されていないのだと思います。
つまり「自分がやりたいことをやっていると思われるプログラムを見つけて来て、その中身が具体的に何をどういう手順で処理してやりたいことをじちゅ減しているかを理解せずに使っている」のでしょう。
まずやらなければならないことは、以下の4行の1行、1行の意味を理解することです。
> open (IN,"test.html"); #index.htmlというHTMLファイルを読み込む
> my @tmp=<IN>;
> close (IN); #ファイルハンドルを閉じる
> print @tmp;
なお、その際、test.htmlの中身も理解しましょう。
そうしないとこのプログラムはアクセスして来たWebブラウザに対してどういう内容のHTMLを送出しているかがわからないからです。
ちなみに、このプログラムはどこかからパクって来たものである場合、パクリ元のプログラムは質問者様の下でちゃんと動いていますか?
動いているとすれば、test.htmlに当たるファイルの中身はどうなっていますか?
全てが“おまじない”のように動いる状況なのでしたらPerlであれ何であれプログラミングをやっているという状態ではないので、ちゃんと基本的な理屈を理解されることです。
CGIプログラムという動的コンテンツを扱われているわけですが、そもそも基本中の基本である静的コンテンツはどう作られていているかや、HTTPの通信ではコンテンツのHTML本文の前にどういうHTTPヘッダーを付けなければならないといったことを理解しましょう。
それがわかれば・・・
> print "Content-type: text/html\n\n";
の有無でなぜ500エラーになったり正常に実行でいたりするのかを近い出来ます。
参考まで。
早速の解答ありがとうございます。
私のやり方として,先達の書いてくださったスクリプトを参考に,
少しずつ自分なりに改変して,動く物を積み重ねていく,
というやり方で,覚えております。
今回,掲載した#以下のコメントと,やろうとしていることが一致してないということは,理解しています。
スクリプトの実行に差し支えないところなので,そのまま残してしまってました。
>動いているとすれば、test.htmlに当たるファイルの中身はどうなっていますか?
これも,test.html の中身として,質問に掲載させていただいております。
>えっと。。。
>この文章の意味をり合い出来ません。
ですが,ファイルに記載されている中身内容を記述を,説明したつもりです。
私がアドバイスいただきたかったのは,print のあるなして,
なぜ,サーバーのイターナルエラーがでたりしなかったりするのかというこです。
open の方法で,あちこちのHPを見ましたが,openの前に,
print の記述のある説明をみていませんでした。
テキストファイルだと,うまくいくのに,htmlだとうまくいかない,その辺のアドバイスがほしかったのですが。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
C言語 関数、変数の宣言について
C言語・C++・C#
-
アセンブリ言語について。
その他(プログラミング・Web制作)
-
Cのプログラムからアクセスできないファイル名の一括変更方法
C言語・C++・C#
-
-
4
C言語について(初心者)
C言語・C++・C#
-
5
IT業で開発をされてる方々に質問なんですが、一日に書かれるコード数ってどれくらいですか? また、最近
その他(プログラミング・Web制作)
-
6
プログラミングに興味があるのですが、作りたいものはありません。 ゲーム機とかパソコンの中身(ソースコ
その他(プログラミング・Web制作)
-
7
プログラミングのやり方ざっくりでいいから教えて
その他(プログラミング・Web制作)
-
8
フロントエンドエンジニアをしていますが、スキルアップのための転職、異動は3年目では早すぎますか? 今
その他(プログラミング・Web制作)
-
9
pythonについて
その他(プログラミング・Web制作)
-
10
C言語のことです。写真(見にくくてすいません)の下のプログラムを実行したいのですが四行目がおかしいと
C言語・C++・C#
-
11
C# で 数式文字列処理を処理する方法
C言語・C++・C#
-
12
Ruby 引数
Ruby
-
13
以下のプログラムの実行結果はどうなると思いますか? その理由も教えてください。
Visual Basic(VBA)
-
14
PHPの勉強してます。 配列のところですが、 実行結果は、9になりますが、 そのロジックを教えてくだ
PHP
-
15
COPYコマンドで、最後に1文字「Hex1A」が付くのはなぜ?外し方は?
その他(プログラミング・Web制作)
-
16
プログラミング言語のバージョン確認について。
その他(プログラミング・Web制作)
-
17
プログラミングc++を全く分からない状態から習得するまでどれくらいかかりますか?なぜ難しいと言われて
C言語・C++・C#
-
18
秀丸エディターでの置き換え
その他(プログラミング・Web制作)
-
19
算術演算子「¥」の意味について
Visual Basic(VBA)
-
20
趣味がプログラミングだと言ってもいい?
その他(プログラミング・Web制作)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
フローチャート 九九
-
perlをバージョンアップしたら...
-
perl の open について教えてく...
-
テキストファイルで提出とは?
-
画像が表示でnull; this.src
-
Strawberry Perl for Windows ...
-
TeraPadエディターの操作方法に...
-
Wallpaper Engineでおすすめの...
-
openした後、closeしないでプロ...
-
Perl言語について。
-
ファイルをディレクトリ分配の...
-
アルファベットに付いて質問し...
-
#!/usr/bin/perlで書きだしたCG...
-
Perlのエラーについてご教授く...
-
perlのflock関数でロックをかけ...
-
AI sisterとは、偽物の人ですか?
-
bashスクリプト
-
ファイルアイコンの左下に緑の□...
-
perlプログラミング 空白行削除
-
perlでリテラル値はメモリにど...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
テキストファイルで提出とは?
-
Perlのエラーについてご教授く...
-
openした後、closeしないでプロ...
-
perlをバージョンアップしたら...
-
INDIRECT 横に再度抽出したい
-
Perl の外部モジュールの利用方法
-
Strawberry Perl for Windows ...
-
Perlで同じフォルダにある任意...
-
perl 正規表現でエラー
-
PerlでUTF-8のファイルの文字列...
-
Perlで特定文字列から特定文字...
-
C言語の問題について
-
どこがおかしいのか教えてくだ...
-
arduino の割り込み処理について
-
perlのflock関数でロックをかけ...
-
bashスクリプト
-
Wallpaper Engineでおすすめの...
-
perlの構文でカンマの意味が分...
-
Perl(Windows)の文法について
-
Windows版のPerlについて
おすすめ情報
>ファイル名 app.cgi
>中身↓
>#!/usr/bin/perl
>print "Content-type: text/html\n\n";
>open (IN,"test.html"); #index.htmlというHTMLファイルを読み込む
>my @tmp=<IN>;
>close (IN); #ファイルハンドルを閉じる
>print @tmp;
>exit;
この部分ですが,下記,▼~▲の間が,app.cgiの内容ということです。
▼
#!/usr/bin/perl
print "Content-type: text/html\n\n";
open (IN,"test.html"); #index.htmlというHTMLファイルを読み込む
my @tmp=<IN>;
close (IN); #ファイルハンドルを閉じる
print @tmp;
exit;
▲
No1さんのご指摘のように,このスクリプトは,あるスクリプトのぱくりです。
ただ,パクりでも,そのぞれの行についての役割は理解して,いるつもりです。
#以下のコメントについては,実行には影響にないので,削除しなかっただけです。
app.cgi から test.html を開くことをやりたかったのです。
test.htmlの中身も掲載したように,最低限のものにしたつもりです。
きちんと検証できていなかったみたいで,
close (IN);
print @tmp
を入れ替えても,エラーでした。
大きな思い違いをしていたようで,ヘッダー情報=htmlファイルの<head>の部分,
と思ってたようです。No4さんのご紹介くださったHPにて,理解できました。
おかげで,print "Content-type: text/html\n\n";がないとエラーになることの理解
もできました。ベストアンサーにさせていただきます。