• ベストアンサー

CGIで外部ファイルに書き込みができません

Perl初心者です。 外部テキストファイルに、HTMLのフォームで入力した情報を書き込み、それを読み込んでHTMLで表示するコードをつくろうとしているのですが、外部ファイルに書き込みができません。(読み込みはできます) コードは以下のとおりです。 #! /usr/bin/perl use strict; my $self = "test.cgi"; my $str = <>; my $filename = "log.txt"; open FH,">$filename"; print FH $str; close FH; my $body; open FH,"<$filename"; my $str2 = <FH>; $body = $str2; close FH; print "Content-type: text/html\n\n"; print <<Q; <html> <head><title>jjj</title></head> <body> <form action = "$self" method = "POST"> <input type = "text" name = "data01" /> <input type = "text" name = "data02" /><br> <input type = "submit" value = "soushinn" /> <hr/> $body </form> </body> </html> Q 環境はMac OS 10.4.11、Apacheを起動して、ローカルでテストしています。 パーミッション等、いろいろ試しましたが、なぜ書き込めないのかよく分かりません。 どなたか原因を教えていただけないでしょうか。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • kumoz
  • ベストアンサー率64% (120/185)
回答No.4

> my $str = <>; CGI では、標準入出力の役割がコンソールとは違うため上のようなコードは使いません。POST で送信すると、 フォームデータは STDIN にセットされるのですが、改行が付かないため読み出しに失敗します。CGI では 通常 read 関数を使って、読み出します。なお、文字列の長さは $ENV{CONTENT_LENGTH} にセットされます。 read(STDIN, my $str, $ENV{CONTENT_LENGTH}); 質問のコードを少し直してみましたので、参考にしてみてください。なお、open には or die (または代わりの Carp の関数) を付けることをお勧めします。また、コードの最初に標準モジュールの CGI::Carp を加えていま す。このようにすると、ファイルのオープンに失敗したり、変数に my を付け忘れたときにブラウザに表示され て何かと便利です。 #! /usr/bin/perl use CGI::Carp qw(fatalsToBrowser); use strict; my $self = "test.cgi"; my $filename = "log.txt"; my $body; if ($ENV{CONTENT_LENGTH}) { open FH,">$filename" or die; read(STDIN, my $str, $ENV{CONTENT_LENGTH}); print FH "$str\n"; close FH; open FH,"<$filename" or die; my $str2 = <FH>; $body = $str2; close FH; } else { $body = "Welcome"; } print "Content-type: text/html\n\n"; print <<Q; <html> <head><title>jjj</title></head> <body> <form action = "$self" method = "POST"> <input type = "text" name = "data01" /> <input type = "text" name = "data02" /><br> <input type = "submit" value = "soushinn" /> <hr/> $body </form> </body> </html> Q

hk-sulo
質問者

お礼

大変丁寧に教えていただき、ありがとうございました! とても勉強になりました。

hk-sulo
質問者

補足

いろいろ細かい点まで教えていただき、ありがとうございます。 試した結果から言うと、書き込みはできませんでした。 (コピーして、改行コードをLFにして試しました) なぜか'or die'の部分に対してエラーが出ます。 'or die'をとると、エラーは出なくなるのですが、書き込みができないのは変わりません。 試しにもっと簡単なコード(以下)を試してみました。 #! /usr/bin/perl use CGI::Carp qw(fatalsToBrowser); use strict; my $str = "sample"; my $filename = "log.txt"; open FH , ">$filename"; print FH "$str\n"; close FH; print "Content-type: text/html\n\n"; print "welcome"; これも、シェルだと動くのですが、ブラウザだとダメでした。どうやらPOSTで送信されたフォームデータを受け取れないのではなく、ファイルに書き込むことができないようです。 また、'or die'でエラーが出る理由もよく分かりません。。 すみません、よろしくお願いします。

その他の回答 (4)

  • Suzi
  • ベストアンサー率38% (130/334)
回答No.5

他の方へのレスからで済みません。 「or die」が出るということは、とにもかくもファイルのところがおかしいと思います。 「log.txt」の大文字や小文字、またはパスなどは合っていますでしょうか。  例えば間違えて半角スペースなどが入っていると小さくて見落としてしまったりもします。  パーミッションは読み込みだけなのでFTPしたままの644/604。逆に777とかだと開かないような記憶があります。

hk-sulo
質問者

お礼

ご指摘、ありがとうございます。 パスは問題なかったので、もう一度パーミッションをいじったら書き込めました! 具体的には、log.txtのパーミッションを666などにして、書き込み可能にし、CGIファイルのパーミッションを755にしました。 ちなみに、手元にあるperlの本では、「log.txtファイルがない場合はCGIを実行すると自動的に生成される」とあったのですが、これもうまくいかない状況でした。 しかし、新しいディレクトリを作成し、そのディレクトリのパーミッションを766など、書き込み可能にし、その中にCGIファイルを入れてブラウザで実行すると、log.txtが自動的に生成されました。 「パーミッション等、いろいろ試した」と言っておきながら、お騒がせして申し訳ありません。 ありがとうございました!

  • Suzi
  • ベストアンサー率38% (130/334)
回答No.3

open FH,">$filename"; @str = <FILE>; close FH; にして、 1) print $str[0]; または、 2) foreach(@str){ print $_; } とかはどうですか。 最初に、open FH,">$filename"; とかがあるとアウトですが。

hk-sulo
質問者

補足

すみません、再度アドバイスいただきましたが、やはり書き込みできません。。。

  • okmotokun
  • ベストアンサー率59% (92/155)
回答No.2

数値定数以外の文字列を変数に代入する場合はクォートする必要があります。  my $str = <>; → my $str = '<>';

hk-sulo
質問者

補足

ご指摘ありがとうございます。 <>はHTMLからPOSTで送られた情報を読み込むためのものとして使っているので、クォートする必要はないと思うのですがどうでしょうか。 一応やってみましたがやはりダメでした。

  • Suzi
  • ベストアンサー率38% (130/334)
回答No.1

open FH,">$filename"; の > は書き込みようで、ファイルが存在すると内容が消去されてしまうと思います。 ================ open FH,"+<$filename"; print FH $str; close FH; print "Content-type: text/html\n\n"; print $str; ================ とかではどうですか? $str が表示されれば、そこからお好きなように。 動作確認していないところから失礼しました。

hk-sulo
質問者

補足

早速のアドバイス、ありがとうございます。 "+<"も試してみましたが、ダメでした。 ちなみに、シェル(ターミナル)では問題なく動作します。 このコードで書いたCGIファイルをsafariなどで開いて入力した内容が、ファイルに書き込まれない、という状況です。 シェルではOKで、ブラウザだとNG、ということです。 情報が足りず、すみません。 引き続きよろしくお願いします。

関連するQ&A