ラベル Perl の投稿を表示しています。 すべての投稿を表示
ラベル Perl の投稿を表示しています。 すべての投稿を表示

2012年12月4日火曜日

PerlのCGIでよくお目見えするInternal Server Error 解決法


PerlのCGIでフォームからpostでデータ取得するサンプルです。
とりあえずhttpdをインストールするあたりから記載していますが、
必要なところから参考にしていただければ。

Amazon Linux の場合、CGI.pmがないのでインストールする手順も記載していますが、
CentOSならおそらくデフォルトインストールされているのでその手順は不要です。

Internal Server Error を発生させその解決法も併せて記載しています。

■構成情報
・OS: Amazon Linux AMI release 2012.09(64bit)
・Perl: 5.10.1


■httpdインストール
[root@ip-10-77-30-12 ~]# yum -y install httpd
(中略)
===========================================================================
 Package              Arch       Version              Repository      Size
===========================================================================
Installing:
 httpd                x86_64     2.2.23-1.25.amzn1    amzn-updates   1.2 M
Installing for dependencies:
 apr                  x86_64     1.4.6-1.10.amzn1     amzn-main      110 k
 apr-util             x86_64     1.4.1-4.13.amzn1     amzn-main       87 k
 apr-util-ldap        x86_64     1.4.1-4.13.amzn1     amzn-main       17 k
 generic-logos        noarch     16.0.0-1.4.amzn1     amzn-main      588 k
 httpd-tools          x86_64     2.2.23-1.25.amzn1    amzn-updates    75 k

Transaction Summary
===========================================================================
(省略)

■CGI動作設定
[root@ip-10-77-30-12 ~]# cd /etc/httpd/conf/
[root@ip-10-77-30-12 conf]# cp -p httpd.conf httpd.conf.org
[root@ip-10-77-30-12 conf]# vi httpd.conf
[root@ip-10-77-30-12 conf]# diff httpd.conf httpd.conf.org
797c797
< AddHandler cgi-script .cgi
---
> #AddHandler cgi-script .cgi
[root@ip-10-77-30-12 conf]#

■サンプルhtml(radio.html)作成
htmlプログラムは表示上の都合のため画像でご勘弁を。

■サンプルcgi(radio.cgi)プログラム作成
[root@ip-10-77-30-12 ~]# vi /var/www/cgi-bin/radio.cgi
[root@ip-10-77-30-12 ~]# cat /var/www/cgi-bin/radio.cgi
#!/usr/bin/perl

use CGI;
$form_data = new CGI;

$goods = $form_data->param('goods');

print "Content-type: text/html\n\n";
print "\n";
print "$goods が購入されました。\n";
print "\n";
[root@ip-10-77-30-12 ~]#

■cgiプログラムテスト実行
[root@ip-10-77-30-12 ~]# perl /var/www/cgi-bin/radio.cgi
Can't locate CGI.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /var/www/cgi-bin/radio.cgi line 3.
BEGIN failed--compilation aborted at /var/www/cgi-bin/radio.cgi line 3.
[root@ip-10-77-30-12 ~]#
エラー発生。
perlモジュールとしてCGI.pmがインストールされているか調査
[root@ip-10-77-30-12 ~]# find `perl -e 'print "@INC"'` -name '*.pm' -print | grep CGI
find: `/usr/local/lib64/perl5': No such file or directory
find: `/usr/local/share/perl5': No such file or directory
[root@ip-10-77-30-12 ~]#
ないのね…。

■CGI.pmインストール
[root@ip-10-77-30-12 ~]# yum -y install perl-CGI
(中略)
 Package        Arch         Version               Repository     Size
=======================================================================
Installing:
 perl-CGI       x86_64       3.51-127.15.amzn1     amzn-main     216 k

Transaction Summary
=======================================================================
Install       1 Package(s)

Total download size: 216 k
Installed size: 434 k
Downloading Packages:
perl-CGI-3.51-127.15.amzn1.x86_64.rpm                | 216 kB     00:00
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing : perl-CGI-3.51-127.15.amzn1.x86_64                    1/1
  Verifying  : perl-CGI-3.51-127.15.amzn1.x86_64                    1/1

Installed:
  perl-CGI.x86_64 0:3.51-127.15.amzn1

Complete!
[root@ip-10-77-30-12 ~]#

■cgiプログラム再テスト
[root@ip-10-77-30-12 ~]# perl /var/www/cgi-bin/radio.cgi
Content-type: text/html

<body>
 が購入されました。
</body>
[root@ip-10-77-30-12 ~]#
エラーは解消。

■ブラウザで動作確認
CGIを実行させると…、
Internal Server Error キター!(T-T)
Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator, root@localhost and inform them of the time the error occurred, and anything you might have done that may have caused the error.

More information about this error may be available in the server error log.

------------------------------------------------------------------------

Apache/2.2.23 (Amazon) Server at 54.xxx.xxx.xxx Port 80
原因はradio.cgiファイルに実行権がないためです。

■実行権追加
[root@ip-10-77-30-12 ~]# chmod 755 /var/www/cgi-bin/radio.cgi
もう一度ブラウザから同じようにCGIを実行させると・・・、
上記のように正しく表示されました。

■ Content-type: text/htmlも大事
下記のように「Content-type: text/html」を出力し忘れたcgiプログラムを作成すると、
[root@ip-10-77-30-12 ~]# vi /var/www/cgi-bin/radio.cgi
[root@ip-10-77-30-12 ~]# cat /var/www/cgi-bin/radio.cgi
#!/usr/bin/perl

use CGI;
$form_data = new CGI;

$goods = $form_data->param('goods');

print "\n";
print "$goods が購入されました。\n";
print "\n";
[root@ip-10-77-30-12 ~]#
期待通り?Internal Server Errorが出現しますのでお忘れなく。

2012年12月2日日曜日

CSVファイルを2次元配列に読み込むperlサンプル


自動販売機の在庫管理を例としてCSVファイルを2次元配列に読み込むperlサンプルです。
まずは行ごとに1次元配列(@csv_array)に読み込み、各行の要素は一度(@line)配列に保持し、
split関数を使用して2次元配列(@line_data)に読み込んでいます。

配列に読み込んだ後の処理は適当です。

配列をCSVファイルに出力する準備として2次元配列(@line_data)をjoin関数を使用して
カンマ区切りの要素とした1次元配列(@line_consolidate)に整形した後に
CSVファイルに出力しています。

■構成情報
・OS: Amazon Linux AMI release 2012.09(64bit)
・Perl: 5.10.1


■読み込むCSVファイル(goods.csv)
商品名,価格,在庫 ファンタ,100,28 キリンレモン,110,24 ポカリスエット,150,31 十六茶,130,18 アクエリアス,140,26 午後の紅茶,160,17 伊右衛門,140,19

■Perlプログラム(inoutcsv.pl)
#!/usr/bin/perl # csvファイルの内容を配列に読み込み、 # 配列の内容をcsvファイルに出力するサンプル ### 読み込みファイル $INPUT = "./goods.csv"; ### 出力ファイル $OUTPUT = "./goods.csv"; ### 配列の中身を初期化 my @csv_array = (); my @line = (); my @line_data = (); my @line_consolidate = (); ### csvファイルの中身を配列に読み込む open (FH, "$INPUT") or die "$!"; @csv_array = ; close (FH); # 要素を各配列に格納 print "要素を配列に格納\n"; print "----------------------\n"; my $i = 0; while ($i <= $#csv_array) { chomp ($csv_array[$i]); @line = split (/,/, $csv_array[$i]); my $j = 0; while ($j <= $#line) { $line_data[$i][$j] = $line[$j]; print "$i行$j番目の要素: $line_data[$i][$j]\n"; $j ++; } $i ++; } print "----------------------\n\n"; ### 商品購入処理 # 何らかの処理がされないと面白くないのでランダムに在庫を減らしています。 # 1行目はヘッダ行なので出力されないように制御。 my $dec = int(rand($#csv_array -1)) + 1; $line_data[$dec][2] = $line_data[$dec][2] -1; print "処理対象行: $dec $line_data[$dec][0]の在庫更新: $line_data[$dec][2]\n\n"; ### csvファイル出力用に配列を整形 print "csvに出力する内容を確認\n"; print "----------------------\n"; $i = 0; while ($i <= $#csv_array) { $line_consolidate[$i] = join(',', @{$line_data[$i]}) . "\n"; print "$line_consolidate[$i]"; $i ++; } print "----------------------\n"; # 配列をファイルへ出力 open (FH, ">$OUTPUT") or die "$!"; print FH @line_consolidate; close (FH); #// 終了 exit(0);

■実行結果確認
$ ./inoutcsv.pl 要素を配列に格納 ---------------------- 0行0番目の要素: 商品名 0行1番目の要素: 価格 0行2番目の要素: 在庫 1行0番目の要素: ファンタ 1行1番目の要素: 100 1行2番目の要素: 28 2行0番目の要素: キリンレモン 2行1番目の要素: 110 2行2番目の要素: 24 3行0番目の要素: ポカリスエット 3行1番目の要素: 150 3行2番目の要素: 31 4行0番目の要素: 十六茶 4行1番目の要素: 130 4行2番目の要素: 18 5行0番目の要素: アクエリアス 5行1番目の要素: 140 5行2番目の要素: 26 6行0番目の要素: 午後の紅茶 6行1番目の要素: 160 6行2番目の要素: 17 7行0番目の要素: 伊右衛門 7行1番目の要素: 140 7行2番目の要素: 19 ---------------------- 処理対象行: 5 アクエリアスの在庫更新: 25 csvに出力する内容を確認 ---------------------- 商品名,価格,在庫 ファンタ,100,28 キリンレモン,110,24 ポカリスエット,150,31 十六茶,130,18 アクエリアス,140,25 午後の紅茶,160,17 伊右衛門,140,19 ----------------------

■出力されたCSVファイル(goods.csv)を確認
$ cat goods.csv 商品名,価格,在庫 ファンタ,100,28 キリンレモン,110,24 ポカリスエット,150,31 十六茶,130,18 アクエリアス,140,25 午後の紅茶,160,17 伊右衛門,140,19
※アクエリアスの在庫が26→25に更新されCSVファイルに出力された。

2012年1月17日火曜日

CentOS6.2 主なバンドルソフトウェアのバージョン

CentOS6.2の主なバンドルソフトウェアのバージョンを紐解いてみたいと思います。
ぶっちゃけrpmコマンド結果をgrepしているだけです。
■apache
[root@centos62 ~]# rpm -qa | grep httpd
httpd-tools-2.2.15-15.el6.centos.x86_64
httpd-manual-2.2.15-15.el6.centos.noarch
httpd-2.2.15-15.el6.centos.x86_64

■perl
[root@centos62 ~]# rpm -q perl
perl-5.10.1-119.el6_1.1.x86_64

■php
[root@centos62 ~]# rpm -q php
php-5.3.3-3.el6_1.3.x86_64

■java
[root@centos62 ~]# java -version
java version "1.6.0_22"
OpenJDK Runtime Environment (IcedTea6 1.10.4) (rhel-1.41.1.10.4.el6-x86_64)
OpenJDK 64-Bit Server VM (build 20.0-b11, mixed mode)

■mysql
[root@centos62 ~]# rpm -qa | grep mysql
mysql-libs-5.1.52-1.el6_0.1.x86_64
mysql-server-5.1.52-1.el6_0.1.x86_64
mysql-connector-odbc-5.1.5r1144-7.el6.x86_64
mysql-5.1.52-1.el6_0.1.x86_64

■samba
[root@centos62 ~]# rpm -qa | grep samba
samba-winbind-clients-3.5.10-114.el6.x86_64
samba-3.5.10-114.el6.x86_64
samba-client-3.5.10-114.el6.x86_64
samba-common-3.5.10-114.el6.x86_64

■NFS
[root@centos62 ~]# rpm -qa | grep nfs
nfs-utils-1.2.3-15.el6.x86_64
nfs-utils-lib-1.1.5-4.el6.x86_64
nfs4-acl-tools-0.3.3-5.el6.x86_64

■FTP
[root@centos62 ~]# rpm -qa | grep vsftpd
vsftpd-2.2.2-6.el6_0.1.x86_64

思いつくままに列挙してみましたが、何か足りてない気も…。

2011年6月28日火曜日

cookie検証

[root@tanyao0b cgi-bin]# cat login.cgi
#!/usr/bin/perl

#フォームからの受け取りをデコードする
&dec;

#クッキーの読み出し
&splt;

#入室用のパスワード
$passw = '0123';

#入力されたパスが正しければ
if ($forminh{'pass'} eq $passw) { &site_form; }

#cookieのパスが正しければ
elsif ($COOKIE{'ckpas'} eq $passw) { &site_cookie; }

# 初期アクセス
print <<"HTML";
Content-type: text/html








統合監視システムへようこそ!
パスワード:
HTML exit; #入力されたパスが正しければ表示するサイトのサブルーチン sub site_form { #クッキーの書き出し print <<"HTML"; Content-type: text/html Set-Cookie: ckpas=$forminh{'pass'}; expires=Tue, 1-Jan-2030 00:00:00 GMT; path=/cgi-bin/; HTML print <<"HTML"; Content-type: text/html site_form 統合監視システムへログイン成功!!
Get from COOKIE: $ENV{'HTTP_COOKIE'}
Get from FORM: $forminh{'pass'}

下記リンクをクリックするとこのページをリロードします。
login.cgi
HTML exit; } #cookieのパスが正しければ表示するサイトのサブルーチン sub site_cookie { print <<"HTML"; Content-type: text/html site_cookie こちらは、統合監視システムです。すでに認証済みです。
Get from COOKIE: $ENV{'HTTP_COOKIE'}
Get from FORM: $forminh{'pass'}

ログアウトはこちら
HTML exit; } #フォームからの値をデコードするサブルーチン sub dec { #フォームからデータを受け取り変数へ入れる read(STDIN, $formin, $ENV{'CONTENT_LENGTH'}); # + 記号を半角スペースに戻す $formin =~ tr/+/ /; #URLエンコードデータをデコード $formin =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; @indata = split (/&/,$formin); #受け取ったデータを&で区切り、配列へ foreach $tmp (@indata) #フォームの要素分(配列分)以下の処理を繰り返す { ($name,$value) = split (/=/,$tmp); # =記号で区切り、名前 と 値 に分ける $forminh{$name} = $value; #区切った名前を付けた連想配列に値を入れる } } #クッキー読み出し用のサブルーチン sub splt { @cookdata = split(/;/,$ENV{'HTTP_COOKIE'}); #クッキーを配列に foreach $tmp (@cookdata) #クッキーデータの有る間処理をする { ($youso,$atai) = split(/=/,$tmp); #要素名と値に区切る $youso =~ s/ //; #要素間のスペース除去 $COOKIE{$youso} = $atai; #要素名の連想配列に値を入れる } } [root@tanyao0b cgi-bin]# cat logout.cgi #!/usr/bin/perl #クッキーの読み出し &splt; #入室用のパスワード $passw = '0123'; #cookieのパスが正しければ if ($COOKIE{'ckpas'} eq $passw) { &site_cookie; } # 初期アクセス print <<"HTML"; Content-type: text/html 認証に失敗している可能性があります。

認証画面はこちら
HTML exit; #cookieのパスが正しければ表示するサイトのサブルーチン sub site_cookie { #クッキーの書き出し print <<"HTML"; Content-type: text/html Set-Cookie: ckpas= ; expires=Tue, 1-Jan-2020 00:00:00 GMT; path=/cgi-bin/; HTML print <<"HTML"; Content-type: text/html site_cookie ログアウトしました。

Get from COOKIE: $ENV{'HTTP_COOKIE'}
Get from FORM: $forminh{'pass'}
Delete Password from Cookie !!

ログイン画面はlogin.cgi
HTML exit; } #クッキー読み出し用のサブルーチン sub splt { @cookdata = split(/;/,$ENV{'HTTP_COOKIE'}); #クッキーを配列に foreach $tmp (@cookdata) #クッキーデータの有る間処理をする { ($youso,$atai) = split(/=/,$tmp); #要素名と値に区切る $youso =~ s/ //; #要素間のスペース除去 $COOKIE{$youso} = $atai; #要素名の連想配列に値を入れる } }

2008年6月14日土曜日

アクセスログ出力サンプル

_____________________________
index_access.pl
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
#!/usr/bin/perl --

#=================================================================
# 時刻設定
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$year += 1900;
$mon = $mon + 1;
$thisday = (Sun,Mon,Tue,Wed,Thu,Fri,Sat)[$wday];

$jikoku = sprintf("%04d/%02d/%02d (%03s) %02d:%02d:%02d", $year, $mon, $mday, $thisday, $hour, $min, $sec);

# 環境変数の取得
$ip = $ENV{'REMOTE_ADDR'}; #// リモート端末のIP アドレス
$port = $ENV{'REMOTE_PORT'}; #// リモート端末のポート番号
$url = $ENV{'HTTP_REFERER'}; #// リモート端末の直前の URL
$blws = $ENV{'HTTP_USER_AGENT'}; #// ブラウザ情報
$path = $ENV{'PATH_INFO'}; #// 現 CGI のパス情報

$rtpc = $ENV{'REMOTE_HOST'}; #// リモート端末のホスト名
$svpc = $ENV{'SERVER_NAME'}; #// サーバのホスト名
$webs = $ENV{'SERVER_SOFTWARE'}; #// ウェブサーバのソフト名と ver
$wcgi = $ENV{'GATEWAY_INTERFACE'}; #// ウェブサーバの CGI ver

#===============================================================


open(FILE,">>index_access.log") or die "$!";
flock(FILE,2);
print FILE "$jikoku,$ip,$port,$url,$rtpc,$blws\n";
flock(FILE,8);
close(FILE);

#// 終了
exit(0);


_____________________________
呼び出し側HTML(一部)
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄