Posts tagged ‘Perl’

CGI.pmを使って、CGIを使っていたが、
GETとPOSTが混在した場合の処理については、
注意が必要だったので、
メモしておきます。

パラメータ
test.cgi?key1=val1とPOSTでkey2=val2が来た場合。

  1.  
  2. use CGI;
  3.  
  4. my $cgi = new CGI;
  5. my $val1;
  6. my $val2;
  7.  
  8. $val1 = $cgi->param(‘key1′);
  9. $val2 = $cgi->param(‘key2′);
  10.  
  11. #↑これだと、val2しか取れない
  12.  
  13. $val1 = $cgi->url_param(‘key1′);
  14. $val2 = $cgi->param(‘key2′);
  15.  
  16. #↑これで取得可能
  17.  
  18.  

GETとPOSTが両方とも存在する場合は、POSTが優先される。
GETの値を取りたい場合は、url_paramで取得可能。

実際、どちらで来るかわからない場合は、こんな風に書くのかなぁ
#同じキー値が届いた場合は、POSTを優先させる

  1.  
  2. use CGI;
  3.  
  4. use $cgi = new CGI;
  5.  
  6. my $val1;
  7. my $val2;
  8.  
  9. $val1 = $cgi->param(‘key1′);
  10. $val2 = $cgi->param(‘key2′);
  11.  
  12. $val1 = $cgi->url_param(‘key1′) if( ! defined($val1) );
  13. $val2 = $cgi->url_param(‘key2′) if( ! defined($val2) );
  14.  
  15.  

CPANに登録されているNet::OpenSSHを使用して、
PerlのスクリプトからSSHで接続してみる。

すでに接続先サーバとキーの交換が終わっている場合

  1.  
  2. use strict;
  3. use Net::OpenSSH;
  4.  
  5. my $host = "xxx.xxx.xxx.xxx";
  6. my $ssh = Net::OpenSSH->new($host);
  7. #エラー処理
  8. die "SSH Connection faild:", $ssh->error if( $ssh->error );
  9.  
  10. my $result = $ssh->capture("コマンド");
  11.  
  12.  

これで、実行結果が$resultに入るようになる。
この場合、SSH側のコマンドでエラーが発生した場合、スクリプトはそのエラーを標準エラー出力に表示する。

次に、エラー出力も取得するやりかた

  1.  
  2. use strict;
  3. use Net::OpenSSH;
  4.  
  5. my $host = "xxx.xxx.xxx.xxx";
  6. my $ssh = Net::OpenSSH->new($host);
  7. #エラー処理
  8. die "SSH Connection faild:", $ssh->error if( $ssh->error );
  9.  
  10. my ($result, $errput) = $ssh->capture2("コマンド");
  11.  
  12.  

capture2メソッドを使用することで、エラー出力も取得でき、
スクリプト内で処理可能となる。

非常に便利なライブラリですね。

データベース向けのテストデータを簡単に作るために、
必要となったので、作ってみた。

  1.  
  2. use strict;
  3. use Time::Local qw( timelocal );
  4.  
  5. #2005年から2012年の間のランダムな日時を作成
  6. #2005年1月1日 00:00:00
  7. my $start_date = timelocal( 0, 0, 0, 1, 0, 105 );
  8. #2012年12月31日 23:59:59
  9. my $end_date = timelocal( 59,59,23,31,11,112 );
  10.  
  11. #$start_dateと$end_dateにはエポック秒数が入っている
  12.  
  13. for( 1..2000 ){
  14.     #ランダムな日付を取得
  15.     my $time = $start_date + int( rand( $end_date - $start_date ) );
  16.     #日付の形式に戻す
  17.     my ( $sec, $min, $hour, $mday, $month, $year, $isdst ) = localtime( $time );
  18.    
  19.     #日付の補正
  20.     $year += 1900;
  21.     $month++;
  22.    
  23.     #文字列整形
  24.     my $date_str = spirntf( "%d-%02d-%02d %02d:%02d:%02d",
  25.                             $year, $month, $mday, $hour, $min, $sec );
  26.  
  27.     print "$date_str\n";
  28. }
  29.  

ちょっと値を書き換えれば、ランダムな日時を取得することができる

以前書いた「LWP::UserAgentを使ってHTTPアクセス」
では、Webに公開されているコンテンツにアクセスするためのもの。

今回は、そのURLが正常、転送される、存在しない、エラーなのかを
判断が必要な場合に使用するためのもの。

LWP::UserAgentで普通に書くとHTTPレスポンスが転送の場合、
自動的に転送してくれて、実際のコンテンツにありつけることができる。

ただ、転送してほしくないケースもあるかと思う。
例えば、画像ファイルが存在しない場合に、ブラウザで見ると、
画像が置き換わっているように見え、存在しないことは分かるが、
それは人の目で判断しているのであって、プログラムは判断していない。

そこで、今回はそのURLが正常なのかどうかを判断するものを
作ったので、メモ。

HTTPレスポンスコードについては、
Studying HTTPを参照させていただいた。

  1.  
  2. use LWP::UserAgent;
  3.  
  4. sub check_http_status{
  5.   my $url = shift;
  6.  
  7.   my $ret;
  8.  
  9.   my $ua = LWP::UserAgent->new;
  10.   #タイムアウトの設定
  11.   $ua->timeout(10);
  12.  
  13.   #エージェントの設定
  14.   $ua->agent();
  15.  
  16.   #リクエストの作成
  17.   my $req = HTTP::Request->new(HEAD => $url);
  18.  
  19.   #リファラーを設定
  20.   $req->referer();
  21.  
  22.   #リクエスト実行
  23.   my $res = $ua->simple_request($req);
  24.  
  25.   #結果判断
  26.   if ($res->is_success) {
  27.     $ret = 1;
  28.   }else{
  29.     $ret = 0;
  30.   }
  31.   #実際のレスポンスコードが欲しい場合は、↓
  32.   print $res->code; #レスポンスコードを表示
  33.   #で取得することができる
  34.  
  35.   return $ret;
  36. }
  37.  
  38.  

ポイントは、simple_requestというメソッドを使うこと。
これを使うことによって、転送レスポンスコードを取得することができる。
#LWP::UserAgentのrequestメソッドは、このsimple_requestメソッドを転送等の場合、
#何回か呼び出しを行っている模様

リクエストで「HEAD」としたのは、コンテンツではなく、URLに対するサーバ側のレスポンスコードが重要だったので、
転送量を抑えるために、HEADとした。

これで、実際のURLが正常(200番代)かどうかが分かるようになった。

新規で起こしたサイトのグーグルのサイトマップを作成したいと思い、
Perlで組んでみた。

CGIのパラーメータが入っているURLの登録を行おうとしたときの注意点があったのでメモ

まず、XMLで書く場合は、CGIのパラメータの&をエスケープする必要がある。
「&」⇒「&」としなくてはならない。
また、日本語(非ASCII文字)に関してもURLエンコードをかける必要がある。

このことに注意しながら、HTML::Templateを使って簡単にクエリを作成、
サイトマップに登録することができた。
#登録したばかりなので、どのくらいでインデックスされるかはわからないんですけど。。。

urlエンコードの掛け方

  1.  
  2. use URI::Escape;
  3.  
  4. my $str = "非ASCII文字列";
  5. my $encoded_str = uri_escape($str);
  6.