<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>igreks開発日記</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/" />
    <link rel="self" type="application/atom+xml" href="http://www.igreks.jp/dev/atom.xml" />
    <id>tag:www.igreks.jp,2008-11-14:/dev//1</id>
    <updated>2010-03-01T17:55:58Z</updated>
    <subtitle>サーバ構築、WEBプログラミング、アフィリエイト、その他試行錯誤の履歴</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Pro 4.22-ja</generator>

<entry>
    <title>dovecotのよくわからんエラー</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/03/dovecot.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.511</id>

    <published>2010-03-01T17:24:52Z</published>
    <updated>2010-03-01T17:55:58Z</updated>

    <summary>久々にメールアドレスでも新しく作ろうと思って、nologinで新規ユーザ作成して...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="サーバ構築" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Post Fix" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="メール配信" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Linux" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[久々にメールアドレスでも新しく作ろうと思って、nologinで新規ユーザ作成してみた。<br />
<br />
thunderbirdでちゃちゃちゃとアカウント設定して、いざ受信って思ったら、<br />
「接続：ホストにログイン情報を送信しています・・・」<br />
のまま音沙汰なし。<br />
<br />
パスワードとかいろいろ確認しても特におかしくないので、とりあえずmaillogを確認したら、こんなメッセージが。<br />
<br />
-----------------------------------------------------------------------------------------<br />
dovecot.... mail_location not set and autodetection failed: Mail storage autodetection failed with home=......<br />
-----------------------------------------------------------------------------------------<br />
<br />
うーん、これはなんだろう。<br />
<br />
なんか雰囲気的に、メールボックスの場所が指定されてないから、メールを取りにいけません的な感じだろうか・・・<br />
<br />
おかしいなあ、前までは普通にユーザ作成してメーラーの設定するだけですぐにいけたんだけどなあ・・・<br />
と思いつつ、とりあえず問題ありそうな「/etc/dovecot.conf」を確認。<br />
<br />
ってゆうか、このファイル一回も中身見たことないし〜。<br />
<br />
メールサーバ入れたときもdovecotの設定なんか一回もやんなかったのに・・・<br />
デフォルトでいままでいけてたんですけどね。<br />
<br />
<br />
でもなんかこの辺が臭かったので、<br />
<br />
-------------------------------------------------------------------------------------------<br />
# Location for users' mailboxes. This is the same as the old default_mail_env<br />
# setting. The default is empty, which means that Dovecot tries to find the<br />
# mailboxes automatically. This won't work if the user doesn't have any mail<br />
# yet, so you should explicitly tell Dovecot the full location.<br />
#<br />
# If you're using mbox, giving a path to the INBOX file (eg. /var/mail/%u)<br />
# isn't enough. You'll also need to tell Dovecot where the other mailboxes are<br />
# kept. This is called the "root mail directory", and it must be the first<br />
# path given in the mail_location setting.<br />
#<br />
# There are a few special variables you can use, eg.:<br />
#<br />
#   %u - username<br />
#   %n - user part in user@domain, same as %u if there's no domain<br />
#   %d - domain part in user@domain, empty if there's no domain<br />
#   %h - home directory<br />
#<br />
# See <doc/wiki/Variables.txt> for full list. Some examples:<br />
#<br />
#   mail_location = maildir:~/Maildir<br />
#   mail_location = mbox:~/mail:INBOX=/var/mail/%u<br />
#   mail_location = mbox:/var/mail/%d/%1n/%n:INDEX=/var/indexes/%d/%1n/%n<br />
#<br />
# <doc/wiki/MailLocation.txt><br />
#<br />
#mail_location = <br />
-------------------------------------------------------------------------------------------<br />
<br />
google様で直訳してみると、locationの設定は必須ですよ〜みたいな感じなのかな？<br />
<br />
とりあえず例のまんま設定してみる。<br />
<br />
-------------------------------------------------------------------------------------------<br />
mail_location = mbox:~/mail:INBOX=/var/mail/%u<br />
-------------------------------------------------------------------------------------------<br />
<br />
てなかんじ。<br />
<br />
すると・・・おお！メーラーがちゃんとメールを読みに行った！<br />
<br />
なんじゃそりゃ。<br />
<br />
<br />
ユーザディレクトリにも「mail」ディレクトリが作成されてる。<br />
さっきまで無かったのに・・・<br />
この「mail」ディレクトリって何なのかわかんなかったけど、dovecotが勝手に作ってるんですね・・・<br />
<br />
<br />
とりあえずpopはOKそうなので、ついでにSMTP（postfix）の方も確認。<br />
/etc/postfix/main.cfを開いて、それっぽい部分を見てみると、<br />
<br />
-------------------------------------------------------------------------------------------<br />
# DELIVERY TO MAILBOX<br />
#<br />
# The home_mailbox parameter specifies the optional pathname of a<br />
# mailbox file relative to a user's home directory. The default<br />
# mailbox file is /var/spool/mail/user or /var/mail/user.  Specify<br />
# "Maildir/" for qmail-style delivery (the / is required).<br />
#<br />
#home_mailbox = Mailbox<br />
#home_mailbox = Maildir/<br />
-------------------------------------------------------------------------------------------<br />
<br />
どうやら、デフォルトのメールボックスは/var/spool/mail/userか、 /var/mail/userで、何もいじらないとここにメールを届けに行くらしい。<br />
というわけで、さっきのdovecotの設定とつじつまがあってるのでOK。<br />
<br />
まあ、ちゃんとした人たちはMaildir形式にちゃんと設定してるんだろうけど、横着な私はこれで問題無し。<br />
<br />
<br />
一応確認のためにpostfixから送信して、dovecotで取りに行ってちゃんと読めたのでめでたし。<br />
<br />
しかし軽く7時間かかったのは痛かった。<br />
<br />
<br />
サーバ立ち上げた時から今まで問題なかったのに、いつからdovecotのデフォルト設定変わったの？って感じ。<br />
<br />
アップデートなんてまったくやってないのに。<br />
<br />
・・・よくわからないなー]]>
        
    </content>
</entry>

<entry>
    <title>MySQL:新しいテーブル構造に合わせてテーブルをコピー</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/02/mysql-1.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.464</id>

    <published>2010-02-18T01:48:51Z</published>
    <updated>2010-03-01T17:24:32Z</updated>

    <summary>前記事（http://www.igreks.jp/dev/2010/01/mys...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="MilkyStep" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="MySQL" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[前記事（<a href="http://www.igreks.jp/dev/2010/01/mysql.html">http://www.igreks.jp/dev/2010/01/mysql.html</a>）のようにALTER TABLEを使って更新するのもいいのだが、できれば構造のテンプレートに合わせて一発でコピーしたい。<br />
<br />
ただ単にテーブルの構造とデータをコピーする場合、普通は、<br />
<br />
---------------------------------------------------------------------------------------<br />
CREATE TABLE sample_new LIKE sample_original<br />
INSERT INTO sample_new SELECT * FROM sample_original<br />
---------------------------------------------------------------------------------------<br />
<br />
<br />
しかし、新しい構造のテーブルにあわせて、構造を変更しながらデータをコピーするといった方法が見つからないため、スクリプトの処理を合わせて実現してみる。<br />あんまりスマートじゃないけど・・・<br /><br />まず、最新の構造のテンプレートを作っておく。<br />
<br />
<br />
■最新のテーブル構造のテンプレート（tbl.pl）<br />
---------------------------------------------------------------------------------------<br />
<br />
package tbl;<br />
<br />
sub conf{<br /><blockquote>my %tbl = (<br /><br /><blockquote>
		'table_a' =&gt; {<br /><blockquote>
			'column'	=&gt; '<br /><blockquote>
				id         INT           AUTO_INCREMENT PRIMARY KEY,<br />
				column_1    VARCHAR(36),<br />
			        column_2    VARCHAR(255),<br />column_3    VARCHAR(255)<br /></blockquote>
			',<br />
			'option'	=&gt; '<br /><blockquote>
				ENGINE = MyISAM DEFAULT CHARSET = utf8<br /></blockquote>
			'<br /></blockquote>
		},<br /><br />
		'table_b' =&gt; {<br /><blockquote>'column'	=&gt; '<br /><blockquote>id INT          NOT NULL AUTO_INCREMENT PRIMARY KEY,<br />column_1 INT,<br />column_2 VARCHAR(255),<br />column_3 VARCHAR(255)<br /></blockquote>',<br />
			'option'	=&gt; '<br /><blockquote>
				ENGINE = MyISAM DEFAULT CHARSET = utf8<br /></blockquote>
			'<br /></blockquote>
		},<br /></blockquote><blockquote><blockquote>・<br />・<br />・<br /></blockquote></blockquote>);<br />return \%tbl;<br /></blockquote>}<br />
				1;<br /><br />
---------------------------------------------------------------------------------------<br /><br /><br />テンプレートを読み込んで新しいテーブルを一時作成し、<br />そのテーブルに既存のテーブルのデータをインポートする。<br /><br />■更新処理（tbl_update.pl）<br />
---------------------------------------------------------------------------------------<br />#!/usr/bin/perl<br /><br />package::main;<br /><br />my $dbh;<br />・<br />・<br />・<br /># この辺でデータベースへの接続処理（詳細割愛）<br /><br />print "Content-type: text/html\n\n";<br /><br />print "&lt;p&gt;データベースの再構築を開始します&lt;/p&gt;\n";<br /><br /># 既存のテーブル名をリストで取得<br />my $sth = $dbh-&gt;prepare("SHOW TABLES LIKE 'hoge_%'") || die $dbh-&gt;errstr();<br />$sth-&gt;execute();<br />my @hoge_tbl = ();<br />while(my @tbl = $sth-&gt;fetchrow_array()){<br /><blockquote>push(@hoge_tbl,$tbl[0]);<br /></blockquote>}<br /><br /># テンプレート読み込み<br />
require "./tbl.pl";<br />
my $tbl = &amp;tbl::conf(); # ※リファレンスで受け取り<br />
<br />foreach(@hoge_tbl){<br /><br /># 既存テーブルのカラム名をリストで取得<br />my @cols = ();<br />my $sth = $dbh-&gt;prepare("DESCRIBE $_") || die $dbh-&gt;errstr();<br />$sth-&gt;execute();<br />
while(my $href = $sth-&gt;fetchrow_hashref()){<br /><blockquote>push(@cols,$href-&gt;{'Field'});&nbsp; # unshiftしちゃだめよ<br /></blockquote>}<br />my $cols = join(',',@cols);<br /><br />#####################################<br /># テーブル名の末尾に個別にIDとかが付いてなければこの処理はいらない<br />$_ =~ /hoge_(.+?)(_.+?)?$/;<br />my $name = $1;<br />######################################<br /><br /># 新しい構造の空テーブルを「pre_***」という名前で一旦作成<br />my $sth = $dbh-&gt;prepare("<br /><blockquote>CREATE TABLE IF NOT EXISTS pre_$_ (<br /><blockquote>$$tbl{$name}{'column'}<br /></blockquote>) $$tbl{$name}{'option'}<br /></blockquote>") || die $dbh-&gt;errstr();<br />$sth-&gt;execute();<br /><br /># 既存のテーブルのデータを、カラム名を明示的に指定して挿入<br /># これをしないとカラムの数が合いませんよ！と怒られる<br />my $sth = $dbh-&gt;prepare("INSERT INTO pre_$_ ($cols) SELECT * FROM $_"); # ※1<br />$sth-&gt;execute();<br /><br />
# 既存のテーブル削除<br />my $sth = $dbh-&gt;prepare("DROP TABLE IF EXISTS $_");<br />$sth-&gt;execute();<br />
<br /># 新しいテーブルのリネーム（"pre_"をとる）<br />my $sth = $dbh-&gt;prepare("ALTER TABLE pre_$_ RENAME $_");<br />$sth-&gt;execute();<br /><br />}<br /><br />print "&lt;p&gt;データベースの再構築が完了しました。&lt;/p&gt;\n";<br />
<br />exit;<br />---------------------------------------------------------------------------------------<br /><br /><br />以上。<br /><br />新しいテーブルにカラムが追加されてる場合は問題ないが、カラムが削除された場合は、多分※1のところでエラーになる・・・<br /><br />こういうの一発でできるSQLないのかなぁ。<br /><br />

]]>
        
    </content>
</entry>

<entry>
    <title>ハッシュの値(value)の重複チェック</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/02/value.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.453</id>

    <published>2010-02-15T04:23:23Z</published>
    <updated>2010-02-18T01:47:27Z</updated>

    <summary>配列関係の重複チェックは一度ハッシュ（%check）に入れると簡単 ------...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="MilkyStep" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[配列関係の重複チェックは一度ハッシュ（%check）に入れると簡単<br />
<br />
<br />
-----------------------------------------------------------------------------------------<br />
<br />
my %hash = (<br />
 a => 'あああ',<br />
 b => 'いいい', <br />
 c => 'ううう',<br />
 d => 'あああ',<br />
 e => 'おおお',<br />
 f => 'あああ'<br />
);<br />
<br />
my %check = ();<br />
<br />
for(values %hash){<br />
 die "$_ が重複してるよ！" if $check{$_};<br />
 $check{$_} = 1; #### 1とかaとか好きなの入れる<br />
}<br />
<br />
-----------------------------------------------------------------------------------------<br />
]]>
        
    </content>
</entry>

<entry>
    <title>LWPのレスポンス確認用メソッドまとめ：Summary of verification methods of HTTP response by LWP</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/02/lwpsummary-of-verification-methods-of-http-response-by-lwp.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.452</id>

    <published>2010-02-06T06:45:30Z</published>
    <updated>2010-02-15T04:18:57Z</updated>

    <summary>LWPを使ったhttpレスポンスの取得には、HTTP::Request(::Co...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="MilkyStep" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[LWPを使ったhttpレスポンスの取得には、HTTP::Request(::Common)モジュールを使ってリクエストのオブジェクトを作っておくと、レスポンス情報を確認するさまざまなメソッドを使用することができる。<br />
<br />
HTTPモジュール群にはまず「HTTP::Message」があり、このオブジェクトには幾つかのヘッダとコンテント（ボディ）取得用のクラスが入ってるが、このクラスは抽象クラスである。<br />
つまりHTTP::RequestとHTTP::Responseのための基本クラスとしてだけ使われ、それ自身のインスタンスは生成されることはない。<br />
<br />
「HTTP::Response」はHTTP形式のレスポンスをカプセル化するクラスである。<br />
このクラスのインスタンスは通常、LWP::UserAgentオブジェクトのrequestメソッドによって作成され返される。<br />
<br />
また、「HTTP::Headers」は同様にHTTP形式のメッセージヘッダをカプセル化するクラスである。<br />
このクラスのインスタンスは通常、HTTP::RequestやHTTP::Responseクラスのメンバー変数として、ライブラリ内部用に作成される。<br />
<br />
つまり、<br />
<br />
my $url = '<a href="http://yahoo.co.jp';">http://yahoo.co.jp';</a><br />
my $ua = LWP::UserAgent->new();<br />
my $req = &HTTP::Request::Common::GET($url);<br />
my $res = $ua->request($req);<br />
<br />
のように、レスポンス用オブジェクト($res)生成しておけば、上の3つのモジュールで定義されているメソッドは全てこのオブジェクト($res)から以下のように参照することができる。<br />
<br />
---------------------------------------------------------------------------------------------------<br />
<br />
（HTTP::Message）<br />
<br />
■$res->protocol([$proto])<br />
・・・そのメッセージに使われるHTTPプロトコルを設定する。protocol()は"HTTP/1.0"または"HTTP/1.1"のような文字列が返る。<br />
<br />
■$res->content([$content])<br />
・・・引数が与えられていれば、コンテントを設定する。引数が無ければ、コンテントは触れられずに返される。<br />
<br />
■$res->add_content($data)<br />
・・・前のコンテントの末尾にさらにデータを追加する。<br />
<br />
■$res->content_ref<br />
・・・コンテント文字列へのリファレンスを返す。<br />
コンテントが巨大であれば、この方法が効率的。また、直接操作が出来る。<br />
例：${$res->content_ref} =~ s/\bfoo\b/bar/g;<br />
<br />
■$res->headers;<br />
・・・HTTP::Headersオブジェクトを返す。<br />
<br />
■$res->headers_as_string([$endl])<br />
・・・HTTP::Headers->as_stringを呼び出す。<br />
<br />
（HTTP::Headers）<br />
<br />
■$res->header($field [=> $value],...)<br />
・・・ヘッダの値を取得または設定する。<br />
ヘッダ・フィールド名は大文字／小文字を区別しない。<br />
引数が無い場合は複数の（$field => $values)の組を受け取る。<br />
$valueを複数設定することにより１回の呼び出しでたくさんのフィールドを更新することも可能。$valuesにはスカラまたはスカラのリストへのリファレンスを指定することができる。<br />
$valueが未定義だったり指定されていなければヘッダは変更されない。<br />
<br />
複数の値を持つフィールドは、スカラ・コンテキストでは","を区切り文字としてつなげられ返される。<br />
<br />
（例）<br />
　$header->header(MIME_Version => '1.0',<br />
　　　　　　User_Agent   => 'My-Web-Client/0.01');<br />
　$header->header(Accept => "text/html, text/plain, image/*");<br />
　$header->header(Accept => [qw(text/html text/plain image/*)]);<br />
　@accepts = $header->header('Accept');<br />
<br />
■$res->scan(\&doit)<br />
・・・ヘッダそれぞれにサブルーチンを適用する。コールバック・ルーチンは２つのパラメータ（フィールド名と１つの値）で呼び出される。<br />
ヘッダが1つ以上の値を持っていれば、ルーチンはそれぞれの値につき1回呼ばれる。コールバック・ルーチンに渡されるフィールド名はHTTP仕様で提案されている大文字／小文字をもち、推奨されている"Good Practice"の順でやってくる。<br />
<br />
■$res->as_string([$endl])<br />
・・・フォーマットされたMIMEヘッダとしてヘッダ・フィールドを返す。<br />
文字列を組み立てるために内部でscan()メソッドを使っているので、結果はHTTP仕様で提案されている大文字小文字で、ヘッダ・フィールドの順序の推奨されている"Good Practice"に従う。<br />
長いヘッダの値はたたまれない。<br />
<br />
オプションのパラメータには使用する行末シーケンスを指定できる。デフォルトは"\n"。<br />
この場合、ヘッダに埋め込まれた"\n"文字は、この行末シーケンスで置きかえられる。<br />
<br />
■$res->push_header($field, $val)<br />
・・・指定されたヘッダに新しいフィールドの値を追加する。<br />
ヘッダ・フィールド名は大文字小文字を区別しない。<br />
同じフィールド名で、値を持たずに指定した場合、前の値が残る。<br />
引数にはスカラやスカラのリストへのリファレンスを指定することが出来る。<br />
<br />
（例）$header->push_header(Accept => 'image/jpeg');<br />
<br />
■$res->remove_header($field,...)<br />
・・・指定された名前を持つヘッダを削除する<br />
<br />
（HTTP::Response）<br />
<br />
■$res->code([$code])<br />
・・・レスポンスコード(301など)を返す。<br />
<br />
■$res->message([$message])<br />
・・・レスポンスメッセージを返す。<br />
<br />
■$res->request([$request])<br />
・・・このレスポンスを発生したリクエストのリファレンスを返す。<br />
ここまでの間に、リダイレクトや認証のリトライがある場合もあるので、$ua->request()メソッドに渡されたものと同じリクエストである必要はない。<br />
<br />
■$res->previous([$previousResponse])<br />
・・・最初のレスポンスがリダイレトクまたは認証されていなければ、レスポンスのチェーンを返す。<br />
<br />
■$res->status_line<br />
・・・文字列"$res->code + $res->message"を返す。<br />
もしmessage属性が設定されていなければ、code（HTTP::Statusを参照にした）の公的な名前に置き換えられる。<br />
<br />
■$res->base<br />
・・・レスポンスのベースURLを返す。<br />
戻り値はURIオブジェクトへのリファレンス。<br />
<br />
ベースURLは以下のいずれかの情報源から１〜３の優先順で取得される。<br />
<br />
　1. ドキュメント内容に埋め込まれたもの：例えばHTMLドキュメント内での<BASE HREF="..."><br />
　2. レスポンスでの"Content-Base:"または"Content-Locatin:"ヘッダ<br />
　　古いHTTP実装との互換性のため、"Base:"ヘッダも探す。<br />
　3. このレスポンスを要求したURL。<br />
　　これはレスポンスの前に、いくつかのリダイレクトを受信しているかもしれないため、$ua->request()メソッドに渡された元のURLでない場合もある。<br />
<br />
 ■$res->as_string<br />
・・・コンテントのプレーンテキストを返す。<br />
主にデバッグのために使われる。引数は指定できない。<br />
<br />
■$res->is_info<br />
■$res->is_success<br />
■$res->is_redirect<br />
■$res->is_error<br />
・・・レスポンスが情報的(informational)であるか、成功したか、リダイレクトであるか、エラーであるかを返す。<br />
（偽ならおそらくundefか0を返す）<br />
<br />
■$res->error_as_HTML()<br />
・・・何のエラーが発生したかを示す完全なHTMLドキュメントが入っている文字列を返す。<br />
このメソッドは$res->is_errorがTRUEのときだけ呼ぶべき。<br />
<br />
■$res->current_age<br />
・・・<draft-ietf-http-v11-spec-07> section 13.2.3.によって指定されたレスポンスの"現在の年齢"("current age")を計算する。<br />
レスポンスの年齢は元のサーバサーバーによって送信されてからの時間。<br />
返される値は累計秒。<br />
<br />
■$res->freshness_lifetime<br />
・・・<draft-ietf-http-v11-spec-07> section 13.2.4.で指定されたそのレスポンスの"新鮮期間"("freshness lifetime")を計算する。<br />
"新鮮期間"はレスポンスが生成されてから終了するまでの時間の長さ。<br />
返される値は累計秒。<br />
<br />
■$res->is_fresh<br />
・・・freshness_lifetime()とcurrent_age()の値をベースに、レスポンスが新鮮であればTRUEを返す。<br />
レスポンスがもはや新鮮でなければ、もう一度取り出されるか、元のサーバによって再評価されるべきである。<br />
<br />
■$res->fresh_until<br />
・・・このエンティティがもはや新鮮ではない時刻を返す。<br />
<br />
<br />
------------------------------------------------------------------------------------------------------<br />
<br />
参考URL：<br />
<a href="http://homepage3.nifty.com/hippo2000/perltips/HTTP/Headers.html">http://homepage3.nifty.com/hippo2000/perltips/HTTP/Headers.html</a><br />
<a href="http://homepage3.nifty.com/hippo2000/perltips/HTTP/Message.html">http://homepage3.nifty.com/hippo2000/perltips/HTTP/Message.html</a><br />
<a href="http://homepage3.nifty.com/hippo2000/perltips/HTTP/Response.html">http://homepage3.nifty.com/hippo2000/perltips/HTTP/Response.html</a><br />
]]>
        
    </content>
</entry>

<entry>
    <title>LWPでwebサイトの文字コード(charset)を取得する:Get the charcter set of a website by LWP)</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/02/lwpwebcharsetget-the-charcter-set-of-a-website-by-lwp.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.451</id>

    <published>2010-02-06T06:28:56Z</published>
    <updated>2010-02-06T06:43:17Z</updated>

    <summary>----------------------------------------...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="HTML" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="MilkyStep" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="apache" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[----------------------------------------------------------------------------------------------<br />
<br />
#!/usr/bin/perl -w<br />
<br />
use strict;<br />
use LWP::UserAgent;<br />
use HTTP::Request::Common;<br />
<br />
# オブジェクト作成<br />
my $ua = LWP::UserAgent->new();<br />
my $url = '<a href="http://yahoo.co.jp';">http://yahoo.co.jp';</a><br />
my $req = &HTTP::Request::Common::GET($url);<br />
<br />
# レスポンスを得る<br />
my $res = $ua->request($req);<br />
<br />
# フィールド名を指定してヘッダを取得<br />
my $con_type = $res->header('Content-Type');<br />
<br />
#処理<br />
if($con_type =~ /shift_jis/i){<br />
　　# (sjis用エンコーディング処理)<br />
}<br />
elsif($con_type =~ /euc-jp/i){<br />
　　# (ujis用エンコーディング処理)<br />
}<br />
elsif($con_type =~ /utf-8/i){<br />
　　# (utf8用エンコーディング処理)<br />
}<br />
　　・<br />
　　・<br />
　　・<br />
<br />
----------------------------------------------------------------------------------------------<br />
<br />
<br />
※charsetをダイレクトに返してくれるメソッドはどうやら無いらしい・・・<br />
あったら教えてください。]]>
        
    </content>
</entry>

<entry>
    <title>Crypt::SSLeayが無くてもLWPでhttpsがリクエストできる件</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/02/cryptssleaylwphttps.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.450</id>

    <published>2010-02-03T00:29:43Z</published>
    <updated>2010-02-06T06:28:27Z</updated>

    <summary>多くの参考サイトや本では、LWPモジュール群を利用してのSSLアクセスには「Cr...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="Linux" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="MilkyStep" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="サーバ構築" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[多くの参考サイトや本では、LWPモジュール群を利用してのSSLアクセスには「Crypt::SSLeay」モジュールが必要と説明されているが、どうやら「Net::SSLaey」モジュールがあれば可能なようだ。<br />
<br />
もちろんサーバにSSL環境（OpenSSLとかmodSSLとか）があるっていうのが前提ではあるが。<br />
<br />
OpenSSLとLWPのつなぎ役をしてくれるのがCrypt::SSLeayだが、もともと、OpenSSLとSSLeayとの高度な機能インタフェースを提供するモジュールが「Net::SSLaey」モジュールである。<br />
<br />
<br />
以下確認作業<br />
<br />
■まず適当なスクリプトでPerlの@INCの中身を確認----------------------------------------------------------------------------------------------<br />
#!/usr/bin/perl<br />
<br />
print "Content-type: text/plain\n\n";<br />
<br />
foreach(@INC){<br />
print $_.'\n';<br />
}<br />
<br />
exit;<br />
----------------------------------------------------------------------------------------------<br />
<br />
■結果↓<br />
<br />
----------------------------------------------------------------------------------------------<br />
/usr/local/lib/perl5/site_perl/5.10.0/i386-linux-thread-multi<br />
/usr/local/lib/perl5/site_perl/5.10.0<br />
/usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi<br />
/usr/lib/perl5/vendor_perl/5.10.0<br />
/usr/lib/perl5/vendor_perl<br />
/usr/lib/perl5/5.10.0/i386-linux-thread-multi<br />
/usr/lib/perl5/5.10.0<br />
/usr/lib/perl5/site_perl<br />
.<br />
----------------------------------------------------------------------------------------------<br />
<br />
■次に、Crypt::SSLeayとNet::SSLeayが入っているか確認↓<br />
<br />
----------------------------------------------------------------------------------------------<br />
（コマンド）<br />
$ su<br />
# cd /<br />
<br />
# find -path *Crypt/SSL*<br />
<br />
#<br />
（↑Crypt::SSLeayは入っていない）<br />
<br />
# find -path *Net/SSL*<br />
<br />
./usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/Net/SSLeay<br />
./usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/Net/SSLeay/Handle.pm<br />
./usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/Net/SSLeay.pm<br />
./usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/auto/Net/SSLeay<br />
./usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/auto/Net/SSLeay/https_cat.al<br />
./usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/auto/Net/SSLeay/do_https4.al<br />
./usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/auto/Net/SSLeay/get_httpx3.al<br />
./usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/auto/Net/SSLeay/get_http.al<br />
./usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/auto/Net/SSLeay/put_http.al<br />
./usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/auto/Net/SSLeay/want_read.al<br />
　　　・<br />
　　　・<br />
　　　・<br />
（以下省略）<br />
<br />
（↑@INCでは「/usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi」にNet::SSLeayが入っている）<br />
----------------------------------------------------------------------------------------------<br />
<br />
■試しに名前を変えてみる↓<br />
<br />
----------------------------------------------------------------------------------------------<br />
# cd /usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/Net<br />
# mv SSLeay.pm SSLeay.pm2<br />
----------------------------------------------------------------------------------------------<br />
<br />
■スクリプト↓でhttpsにリクエストしてみる<br />
<br />
----------------------------------------------------------------------------------------------<br />
#!/usr/bin/perl<br />
<br />
use strict;<br />
use LWP::UserAgent;<br />
use HTTP::Request::Common;<br />
<br />
my $ua = LWP::UserAgent->new();<br />
<br />
my $url = "<a href="https://www.hogehoge.jp">https://www.hogehoge.jp</a>"; # 実在するセキュアサイト<br />
<br />
$request = &HTTP::Request::Common::GET($url);<br />
$response = $ua->request($request);<br />
<br />
print "Content-type: text/plain\n\n";<br />
print $response->status_line;<br />
<br />
exit;<br />
----------------------------------------------------------------------------------------------<br />
<br />
■実行結果↓<br />
<br />
----------------------------------------------------------------------------------------------<br />
<br />
 501 Protocol scheme 'https' is not supported<br />
<br />
（httpsプロトコルはサポートしていません）<br />
----------------------------------------------------------------------------------------------<br />
<br />
■SSLeay.pmを元に戻す↓<br />
<br />
----------------------------------------------------------------------------------------------<br />
# mv SSLeay.pm2 SSLeay.pm<br />
----------------------------------------------------------------------------------------------<br />
<br />
■さっきのスクリプトをもう一度実行↓<br />
<br />
----------------------------------------------------------------------------------------------<br />
<br />
 302 Found<br />
<br />
（ファイルが存在します＝接続成功）<br />
----------------------------------------------------------------------------------------------<br />
<br />
<br />
めでたしめでたし。<br />
]]>
        
    </content>
</entry>

<entry>
    <title>特定のプロセスを実行しているファイル名を調べる</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/01/post-5.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.446</id>

    <published>2010-01-27T11:38:50Z</published>
    <updated>2010-02-03T00:20:18Z</updated>

    <summary>あるプロセスがサーバに過大な負荷をかけているとき、その犯人と、原因のプログラムフ...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="Linux" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="サーバ構築" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[あるプロセスがサーバに過大な負荷をかけているとき、その犯人と、原因のプログラムファイルを発見する一番早い（？）方法。<br />
<br />
<br />
まずtopコマンドやpsコマンドで、そのプロセスのプロセス番号を調べる。<br />
<br />
-------------------------------------------------------------------------------------------<br />
<br />
$ su<br />
<br />
# top<br />
<br />
-------------------------------------------------------------------------------------------<br />
<br />
<br />
プロセス番号がわかったら、<br />
<br />
-------------------------------------------------------------------------------------------<br />
<br />
# ls -l /proc/(プロセス番号)/exe <br />
<br />
-------------------------------------------------------------------------------------------<br />
<br />
として、実行ファイルのシンボリックリンクを参照する。<br />
※エディタで直接/proc/(プロセス番号)/exe にアクセスしてもバイナリファイルなので見れません。<br />
<br />
<br />
結果↓<br />
<br />
------------------------------------------------------------------------------------------<br />
<br />
lrwxrwxrwx 1 hoge.hoge 0 2010-01-27 05:23 <br />
/proc/プロセス番号/exe -> /home/●●/hoge/○○○<br />
<br />
------------------------------------------------------------------------------------------<br />
<br />
つまり「●●」が犯人で「○○○」が問題のファイル。<br />
<br />
<br />
<br />
あとは犯人に警告するなりプロセスをkillするなりご自由に。]]>
        
    </content>
</entry>

<entry>
    <title>WEBサーバからアクセスできない場所(DocumentRoot外)のファイルをダウンロードさせる</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/01/webdocumentroot.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.445</id>

    <published>2010-01-15T01:51:54Z</published>
    <updated>2010-01-15T02:01:40Z</updated>

    <summary>DocumentRoot以外の場所にあるファイルをダウンロードさせようとして、プ...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="Linux" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="apache" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[DocumentRoot以外の場所にあるファイルをダウンロードさせようとして、プログラム側で「Location」させても、普通はアクセスできない。<br />
<br />
そういった場合は前記事（<a href="http://www.igreks.jp/dev/2009/10/perlmysql2.html">http://www.igreks.jp/dev/2009/10/perlmysql2.html</a>）の応用で、「cat」コマンドを利用するとダウンロードできるようになる。<br />
<br />
<br />
-----------------------------------------------------------------------<br />
<br />
#!/usr/bin/perl -w<br />
<br />
use strict;<br />
<br />
my $dir = '../../hoge'; #Documentroot外のディレクトリ<br />
my $file = 'huga'; #その中にあるファイル<br />
<br />
print "Content-Type: application/octet-stream\n";<br />
print "Content-Type: application/download; name=$file\n";<br />
print "Content-Disposition: attachment; filename=$file\n";<br />
print "\n";<br />
#### print content<br />
system "cat $dir/$file";<br />
<br />
exit;<br />
<br />
-----------------------------------------------------------------------<br />
<br />
<br />
※DocumentRoot以下に置いてBasic認証かけるよりは安全？<br />
※LWP転送するときもOK<br />
<br />
]]>
        
    </content>
</entry>

<entry>
    <title>MySQL:テーブルに特定のカラムが無ければ追加</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2010/01/mysql.html" />
    <id>tag:www.igreks.jp,2010:/dev//1.443</id>

    <published>2010-01-07T20:41:00Z</published>
    <updated>2010-01-15T01:51:40Z</updated>

    <summary>SQLだけでこういう処理をする方法が調べてもわからないので、スクリプト側でチェッ...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="MilkyStep" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="MySQL" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[SQLだけでこういう処理をする方法が調べてもわからないので、スクリプト側でチェックしてみる。<br />
<br />
メイン<br />
------------------------------------------------------------------------------------------<br />
#!/usr/bin/perl -w<br />
<br />
use strict;<br />
use DBI;<br />
require './db.pl';<br />
<br />
&db::open();<br />
<br />
　my $table = 'table_name';<br />
　##追加カラム情報セット<br />
　my @add = (<br />
　　['field1'		,'INT'				],<br />
　　['field2'	,'VARCHAR(255)'	],<br />
　　['field3'		,'DATE'				],<br />
　　['field4'		,'INT',			],<br />
　　['field5'		,'VARCHAR(255)'	],<br />
　　['field6'		,'VARCHAR(255)'	],<br />
　　['field7'		,'INT'				]<br />
　);<br />
　my $cols = '';<br />
　##現在のテーブル情報を取得<br />
　&db::query("DESCRIBE $table");<br />
　while(my $href = $db::sth->fetchrow_hashref()){<br />
　　##カラム名をセット<br />
　　$cols .= '<>'.$href->{'Field'}.'<>';<br />
　}<br />
　##無ければ追加<br />
　foreach(@add){<br />
　　if($cols !~ /<>$_[0]<>/){<br />
　　　　&db::query("ALTER TABLE $table ADD $_[0] $_[1]");<br />
　　}<br />
　}<br />
<br />
&db::close();<br />
exit;<br />
---------------------------------------------------------------------------------------<br />
<br />
<br />
<br />
DB接続(db.pl)<br />
---------------------------------------------------------------------------------------<br />
package db;<br />
<br />
use strict;<br />
<br />
sub open{<br />
	my $dbs = "DBI:mysql:dbname:dbhost";<br />
	our $dbh = DBI->connect($dbs,dbuser,dbpass);<br />
	if(!$dbh){<br />
		die "データベースに接続できません";<br />
	}<br />
}<br />
<br />
sub query{<br />
	my ($sql) = @_;<br />
	our $sth = $db::dbh->prepare($sql) || die $db::dbh->errstr();<br />
	my $exec = $sth->execute || die $sth->errstr();<br />
	return $exec;<br />
}<br />
<br />
sub close{<br />
	$db::sth->finish;<br />
	$db::dbh->disconnect;<br />
}<br />
<br />
1;<br />
---------------------------------------------------------------------------------------<br />
]]>
        
    </content>
</entry>

<entry>
    <title>実行中プロセスの監視（TOP）</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2009/12/top.html" />
    <id>tag:www.igreks.jp,2009:/dev//1.423</id>

    <published>2009-12-17T17:09:08Z</published>
    <updated>2010-01-07T20:40:42Z</updated>

    <summary>実行中のプロセスのCPU使用率やメモリ占有率などをリアルタイムで監視するUNIX...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="Linux" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="apache" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="サーバ構築" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[実行中のプロセスのCPU使用率やメモリ占有率などをリアルタイムで監視するUNIXコマンド。<br />
<br />
-----------------------------------------------------------------<br />
<br />
$ su （rootになる）<br />
<br />
# top<br />
<br />
（プロセス一覧が表示される）<br />
<br />
<br />
"q"で終了<br />
----------------------------------------------------------------<br />
<br />
以上。<br />
<br />
<br />
オプションとして便利なのは、<br />
<br />
-d: 更新間隔を指定する:  -d ss.tt (秒.10分の1秒)<br />
-u: 指定した実効UIDかユーザ名にマッチするプロセスだけをモニターする:  -u somebody<br />
<br />
<br />
例えばWEBサーバが実効しているプロセスだけを0.5秒間隔に確認したい場合は、<br />
<br />
--------------------------------------------<br />
# top -d 0.5 -u apache<br />
--------------------------------------------<br />
<br />
でOK。]]>
        
    </content>
</entry>

<entry>
    <title>perlでSMTPサーバを指定してメール送信（TLS/SSL接続も可）</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2009/12/perlsmtptlsssl.html" />
    <id>tag:www.igreks.jp,2009:/dev//1.422</id>

    <published>2009-12-16T05:07:51Z</published>
    <updated>2009-12-17T17:08:32Z</updated>

    <summary>とりあえずサンプルスクリプト↓ ------------------------...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="MilkyStep" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="メール配信" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[とりあえずサンプルスクリプト↓<br />
<br />
-----------------------------------------------------------------------<br />
<br />
use strict;<br />
use CGI::Carp qw(fatalsToBrowser);<br />
use Net::SMTP;<br />
use Net::SMTP::SSL;<br />
use Net::SMTP::TLS;<br />
use Encode qw(from_to encode);<br />
<br />
#メールアドレス設定<br />
my $from = 'hoge@gmail.com';<br />
my $mailto= 'huga@nantoka.com';<br />
<br />
#件名設定<br />
my $subject = 'SMTPを指定してメール送信！';<br />
from_to($subject, 'shiftjis', 'iso-2022-jp');<br />
encode('MIME-Header-ISO_2022_JP', $subject);<br />
<br />
#メールヘッダー設定<br />
my $header = << "MAILHEADER";<br />
From: $from<br />
To: $mailto<br />
Subject: $subject<br />
Mime-Version: 1.0<br />
Content-Type: text/plain; charset = 'ISO-2022-JP"<br />
Content-Trensfer-Encoding: 7bit<br />
<br />
MAILHEADER<br />
<br />
#メール本文設定<br />
my $message = << 'MAILBODY';<br />
本日は晴天なり。<br />
<br />
あああいいいううう<br />
さよーなら！<br />
MAILBODY<br />
<br />
#文字コードをJISに変換<br />
from_to($message, 'shiftjis', 'iso-2022-jp');<br />
<br />
#SMTP設定（適宜変更してください）<br />
my $server = 'smtp.gmail.com';　#ホスト名<br />
my $auth = 1;　#SMTPAuthを使用する場合は1<br />
my $tls = 0;　#TLS接続を使う場合は1<br />
my $ssl = 1;　#SSL接続を使う場合は1<br />
my $port = 465;　#ポート指定。指定しないと25番が勝手に設定される<br />
my $user = 'hoge@gmail.com';　#SMTPAuthのユーザ名<br />
my $pass = 'passwaord';　#SMTPAuthのパスワード<br />
<br />
#メール送信オブジェクト設定<br />
my $smtp = '';<br />
<br />
#TLSのときは、オブジェクト生成時にAuthデータを渡す<br />
if($tls){<br />
　$smtp = Net::SMTP::TLS->new(<br />
　　$server,<br />
　　Port => $port	,<br />
　　User => $user	,<br />
　　Password	 => $pass<br />
　) || die "Connect failed over tls";<br />
}<br />
elsif($ssl){<br />
　$smtp = Net::SMTP::SSL->new(<br />
　　$server,<br />
　　Port => $port<br />
　) || die "Connect failed over ssl";<br />
}<br />
else{<br />
　$smtp = Net::SMTP->new($server, Port => $port) || die "Connect failed";<br />
}<br />
if(!$tls && $auth){<br />
　$smtp->auth($user, $pass) || die "auth failed";<br />
}<br />
<br />
#メール送信<br />
$smtp->mail($from);<br />
$smtp->to($mailto);<br />
$smtp->data();<br />
$smtp->datasend($header);<br />
$smtp->datasend($message);<br />
$smtp->dataend();<br />
$smtp->quit;<br />
<br />
print &lt;&lt;EOM;<br />
Content-type: text/html<br />
<br />
送信しました～！<br />
EOM<br />
<br />
exit;<br />
1;<br />
<br />
---------------------------------------------------------------------------------<br />
<br />
※Net::SMTP::SSLおよびNet::SMTP::TLSを使うには、IO::Socket::SSLモジュールが必要。<br />
※IO::Socket::SSLをインストールするには、Net::SSLeayモジュールが必要<br />
※試したところ、gmailの場合は、TLS使用＆ポート587でも送信できた。<br />
※例ではエンコードにEncodeモジュールを使っているが、Jcodeとか使いたい人はお好きなように。]]>
        
    </content>
</entry>

<entry>
    <title>一度requireされたファイルをもう一度読み込む</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2009/12/require.html" />
    <id>tag:www.igreks.jp,2009:/dev//1.421</id>

    <published>2009-12-12T09:36:35Z</published>
    <updated>2010-02-17T17:01:42Z</updated>

    <summary>自動でファイルの書き換えをした場合とかに、最後に古いファイル・新しいファイルのチ...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="MilkyStep" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[自動でファイルの書き換えをした場合とかに、最後に古いファイル・新しいファイルのチェックを行うために辿り着いた作戦。<br />
<br />
新しい同名・同パッケージ名のファイルを別のディレクトから"require"すればOK。<br />
同名のパッケージ名が新しく読み込んだパッケージで上書きされる。<br />
<br />
ただし、useはコンパイル時に参照されるからだめかも知れない。<br />
試してないけど。<br />
<br />
---------------------------------------------------------------------------------------------<br />
<br />
sub update_files_and_check{<br />
<br />
　my $dir = '.';　##　古いファイルが入ったディレクトリ<br />
　###　一度古いfile_list.plを読み込む<br />
　require "$dir/file_list.pl";<br />
　print "<p>現在あるファイルは、</p>\n";<br />
　foreach(@file_list::req){<br />
　　print $_ ."<br />\n";<br />
　}<br />
　print "です。";<br />
<br />
　my $dir = '.';　##　古いファイルが入ったディレクトリ<br />
　my $newdir = './newdir'; ## 新しいファイルが入ったディレクトリ（この中に新しいfile_list.plも入っている）<br />
<br />
<br />
　###　ファイル書き換え<br />
<br />
　opendir(NEW_DIR,$new_dir) || die "Can't open $new_dir !";<br />
　　while(my $doc = readdir(NEW_DIR)){<br />
　　　if($doc !~ /^\.+$/){<br />
　　　　open(FILE,"$new_dir/$doc") || die "Can't open $new_dir/$doc !";<br />
　　　　my $buff = '';<br />
　　　　binmode FILE;<br />
　　　　while(<FILE>){<br />
　　　　　$buff .= $_;<br />
　　　　}<br />
　　　　close(FILE);<br />
　　　　if(-e "$dir/$doc"){<br />
　　　　　unlink "$dir/$doc" || die "Can't delete $dir/$doc!";<br />
　　　　}<br />
　　　　open(FILE,">$dir/$doc") || die "Can't open $dir/$doc !";<br />
　　　　flock(FILE,2);<br />
　　　　print FILE $buff;<br />
　　　　flock(FILE,8);<br />
　　　　close(FILE);<br />
　　　}<br />
　　}<br />
　closedir();<br />
<br />
　###　チェック＆不要ファイル削除<br />
　if(! eval "require $new_dir/file_list.pl;"){<br />
　## ↑ のrequireが成功すれば、この時点で変数「@file_list::xxx」が上書きされる<br />
　## "require $dir/file_list.pl;" にしてしまうと、最初にすでに読み込んでるので失敗する。<br />
<br />
　　print "新しいファイルが参照できません。";<br />
　　exit;<br />
　}<br />
　foreach(@file_list::req){<br />
　　if(!-e "$dir/$_"){<br />
　　　print "$_が見つかりません！！";<br />
　　　exit;<br />
　　}<br />
　}<br />
　foreach(@file_list::des){<br />
　　if(-e "$dir/$_"){<br />
　　　unlink "$dir/$_" || die "$dir/$_が削除できません！";<br />
　　}<br />
　}<br />
}<br />
<br />
---------------------------------------------------------------------------------------------<br />
<br />
<br />
（書き換えられた新しいfile_list.pl）<br />
------------------------------------------------------------------------------------<br />
package file_list;<br />
<br />
use strict;<br />
<br />
### 今回必要なファイル<br />
our @req = ( 'aaa.pl','bbb.pl','ccc.txt');<br />
<br />
### 不要になったファイル<br />
our @des = ('ddd.pl','eee.pl');<br />
<br />
1;<br />
------------------------------------------------------------------------------------]]>
        
    </content>
</entry>

<entry>
    <title>perl2exeに四苦八苦</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2009/11/perl2exe.html" />
    <id>tag:www.igreks.jp,2009:/dev//1.420</id>

    <published>2009-11-17T06:51:51Z</published>
    <updated>2009-12-12T09:32:07Z</updated>

    <summary>かねてから気になっていたperl2exe（perlスクリプトファイルを実行ファイ...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="Linux" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="MySQL" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="apache" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="サーバ構築" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[かねてから気になっていたperl2exe（perlスクリプトファイルを実行ファイルにしてくれるソフト）についに挑戦。<br />
<br />
Win32環境での情報などは結構転がってるのだが、Unix版で参考になるサイトがないので、仕方なく本家のユーザーマニュアルを読みながらやってみる。<br />
<br />
まずは本家からダウンロード。<br />
<a href="http://www.indigostar.com/perl2exe.htm">http://www.indigostar.com/perl2exe.htm</a><br />
<br />
<br />
私の場合はperl5.10.0でLinux上でコンパイル予定なので、<br />
<br />
・Perl2Exe V9.100 for Linux (Jan 18 2008) <br />
<br />
↑これを選んでダウンロード＆解凍。<br />
<br />
<br />
<br />
なにやらマニュアルを見ると、<br />
<br />
・exeファイルの作り方は、コマンドにて、<br />
　「perl2exe yourscript.pl」<br />
とするだけ。ふむふむ。<br />
<br />
・特別なモジュールを読み込む場合は、スクリプト中に<br />
　　#perl2exe_include "somemodule.pm";<br />
的なことを書けばよいと・・・<br />
<br />
まあこの辺はWin32版と同じだな。<br />
<br />
<br />
ほんでもって、Unixホストで動かす場合は、同梱されてるインタプリタじゃなくて、動かしてるサーバのインタプリタとコア/ローカルモジュールを使用する設定にできるらしい。<br />
<br />
後々、こっちの方が楽そうなので、切り替えてみる。<br />
<br />
--------------------------------------------------------------------<br />
cd ~/perl2exe<br />
rm -rf perl5<br />
perl ./setup_perl2exe.pl<br />
--------------------------------------------------------------------<br />
<br />
「切り替えました！」的なことが表示されたので、多分OK。<br />
<br />
<br />
<br />
とりあえず試しに使ってみる。<br />
<br />
まず最初に、<br />
--------------------------------------------------------------------<br />
cd ~/perl2exe<br />
./setup<br />
--------------------------------------------------------------------<br />
<br />
<br />
実行ファイル生成<br />
--------------------------------------------------------------------<br />
cd ~/perl2exe<br />
./perl2exe hellocgi.pl<br />
--------------------------------------------------------------------<br />
<br />
<br />
同じディレクトリに「hellocgi」という実行ファイル（バイナリファイル）ができた！！<br />
<br />
<br />
とりあえず動作確認。<br />
--------------------------------------------------------------------<br />
cd ~/perl2exe<br />
./hellocgi<br />
--------------------------------------------------------------------<br />
（あくまで実行ファイルなのでファイル名を指定するだけ）<br />
<br />
・・・・よっしゃ成功！！<br />
<br />
<br />
<br />
次に、WEBサーバ（ブラウザ）から実行できるか実験。<br />
<br />
マニュアルにはtelnetを使って・・・みたいなこと書いてあったけど、面倒くさいんで、<br />
<br />
#!/usr/bin/perl -w<br />
<br />
system "./hellocgi";<br />
<br />
exit;<br />
<br />
とだけ書いたperlスクリプトを実行ファイルと同じ場所に置いて、このファイルにアクセスする。<br />
<br />
<br />
よしよし、ちゃんと表示される。html出力もOKですな♪<br />
<br />
<br />
<br />
<br />
じゃあいよいよ、もっと複雑なDBが絡んだスクリプトに挑戦してみようってことで、やってみたのだが、もちろん一発でうまくいくわけがなく、以下のエラーが連発。<br />
<br />
Warning: Can't locate VMS/Stdio.pm<br />
    at /usr/lib/perl5/5.10.0/File/Temp.pm line 149<br />
    @INC = /usr/local/lib/perl5/site_perl/5.10.0/i386-linux-thread-multi, /usr/local/lib/perl5/site_perl/5.10.0, /usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi, /usr/lib/perl5/vendor_perl/5.10.0, /usr/lib/perl5/vendor_perl, /usr/lib/perl5/5.10.0/i386-linux-thread-multi, /usr/lib/perl5/5.10.0, ., .<br />
<br />
Warning: Can't locate Compress/Bzip2.pm<br />
    at /usr/local/lib/perl5/site_perl/5.10.0/HTTP/Message.pm line 315<br />
    @INC = /usr/local/lib/perl5/site_perl/5.10.0/i386-linux-thread-multi, /usr/local/lib/perl5/site_perl/5.10.0, /usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi, /usr/lib/perl5/vendor_perl/5.10.0, /usr/lib/perl5/vendor_perl, /usr/lib/perl5/5.10.0/i386-linux-thread-multi, /usr/lib/perl5/5.10.0, ., .<br />
<br />
Warning: Can't locate Compress/Bzip2.pm<br />
    at /usr/local/lib/perl5/site_perl/5.10.0/HTTP/Message.pm line 447<br />
    @INC = /usr/local/lib/perl5/site_perl/5.10.0/i386-linux-thread-multi, /usr/local/lib/perl5/site_perl/5.10.0, /usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi, /usr/lib/perl5/vendor_perl/5.10.0, /usr/lib/perl5/vendor_perl, /usr/lib/perl5/5.10.0/i386-linux-thread-multi, /usr/lib/perl5/5.10.0, ., .<br />
<br />
Warning: Can't locate Compress/Bzip2.pm<br />
    at /usr/local/lib/perl5/site_perl/5.10.0/HTTP/Message.pm line 496<br />
    @INC = /usr/local/lib/perl5/site_perl/5.10.0/i386-linux-thread-multi, /usr/local/lib/perl5/site_perl/5.10.0, /usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi, /usr/lib/perl5/vendor_perl/5.10.0, /usr/lib/perl5/vendor_perl, /usr/lib/perl5/5.10.0/i386-linux-thread-multi, /usr/lib/perl5/5.10.0, ., .<br />
<br />
<br />
（以下省略）<br />
<br />
<br />
<br />
チーン。<br />
<br />
まあ、エラーの言ってる意味はわかるのだが、Compress/Bzip2とか、聞いたこと無いようなモジュールまで要求してきやがる。<br />
<br />
どうやら動作条件に関係なく、モジュール中にuseとかrequireとかの命令があったら、evalで呼ばれてても、とにかくそのモジュールはロードしなきゃならん仕様らしい。<br />
<br />
<br />
仕方ないからインストールしてやるかと思い、cpan2rpm使おうとしたら「見つかりません！」的な。<br />
<br />
ここまできたら、全部入れてやればいいんだろと思い、全部cpanからダウンロードしてきてmake installを実施。<br />
<br />
しかしインストール中に今度は、<br />
<br />
/bin/sh: gcc: command not found......<br />
<br />
Cコンパイラまで追加すんのかよ！と思いつつ、こちらのサイト<br />
<a href="http://memorva.jp/memo/linux/gcc_curses.php">http://memorva.jp/memo/linux/gcc_curses.php</a><br />
を参考にしつつ、gccをインストール。<br />
<br />
--------------------------------------------------------<br />
yum install gcc*<br />
--------------------------------------------------------<br />
<br />
まあyumで一発だからいいけど。<br />
<br />
<br />
これでようやく要求された全てのモジュールのmake install が完了。<br />
<br />
インストール中に何やらいっぱい警告だのエラーだの表示されたけど、とりあえずpmファイルが入ったからいいや的な。<br />
<br />
<br />
そしてもう一度実行ファイルを生成！<br />
<br />
・・・お？<br />
<br />
今度はエラーが出ない。<br />
<br />
イエーイ！コンパイル成功〜〜〜〜！<br />
<br />
さっそく実行〜！<br />
<br />
<br />
あれ？<br />
<br />
Software error:<br />
<br />
DynaLoader object version 1.0801 does not match $DynaLoader::VERSION 1.08 at PERL2EXE_STORAGE/DynaLoader.pm line 93.<br />
Compilation failed in require at PERL2EXE_STORAGE/DBI.pm line 157.<br />
BEGIN failed--compilation aborted at PERL2EXE_STORAGE/DBI.pm line 157.<br />
Compilation failed in require at ** line 15.<br />
BEGIN failed--compilation aborted at ** line 15.<br />
<br />
<br />
・・・うーむ・・<br />
<br />
どうやらDBIの設定がいろいろ必要らしい。<br />
<br />
<br />
苦戦は続く・・・<br />
<br />
<br />
<br />
そして改めて説明をよく見ると、「Mysqlを使用する場合は、DBD::Mysql_PPを使用してください」<br />
みたいなことが書かれている・・・<br />
<br />
ということは、通常のCを使うデータベースドライバが使えないっつーことか。<br />
<br />
このあたりで、ひょっとすると、これはものすごく使えないソフトなのでは・・・という不安がよぎる。<br />
<br />
<br />
調べてみると案の定、Mysql_PPはいつまでたってもバージョンが0代だし、処理がくそ遅いという評判。<br />
<br />
<br />
まあ全てPurePerlでやろうってんだからそうなるだろうな。<br />
<br />
さらにMysql_PPの依存モジュールであるNet::Mysqlモジュールでもようわからんエラーが続出。<br />
<br />
<br />
<br />
<br />
そして、ついに対応するのをあきらめた私。<br />
<br />
<br />
<br />
結論：<br />
<br />
データベース連携するプログラムはPerl2exeで（気軽に）使えない。<br />
そうじゃないものなら使用する価値はまあまあある。<br />
ただしスクリプトにモジュール名が書いてあったら必ず必要。<br />
<br />
<br />
以上、ご参考までに。<br />
]]>
        
    </content>
</entry>

<entry>
    <title>ディレクトリの中を子ディレクトリ内も含め全て出力</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2009/11/post-4.html" />
    <id>tag:www.igreks.jp,2009:/dev//1.419</id>

    <published>2009-11-14T03:49:53Z</published>
    <updated>2009-11-17T06:51:34Z</updated>

    <summary>おそらくこんなことするモジュールとかあると思うんだけど、簡単そうなので自力で。 ...</summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="Perl" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[おそらくこんなことするモジュールとかあると思うんだけど、簡単そうなので自力で。<br />
<br />
ただしperl5.6以降限定。<br />
<br />
----------------------------------------------------------------------------------------------<br />
use strict;<br />
<br />
my $target_dir = './dir';<br />
<br />
print "Content-type: text/plain\n\n";<br />
&read_all($target_dir);<br />
<br />
sub read_all{<br />
　my ($dir) = @_;<br />
　opendir(my $dh,$dir)|| die "Directory open error :$dir";<br />
　　print '__DIR_'.$dir.'_START__'."\n";<br />
　　while(my $doc = readdir($dh)){<br />
　　　if($doc !~ /^\.+$/){<br />
　　　　if(-d "$dir/$doc"){<br />
　　　　　&read_all("$dir/$doc");　##ループ<br />
　　　　}<br />
　　　　elsif(-e "$dir/$doc" && $doc =~ /^[\d\w]+\.[\d\w]+$/){　##ここの正規表現はお好きなように<br />
　　　　　open(FILE,"$dir/$doc") || die "File open error :$dir/$doc";<br />
　　　　　　print '__FILE_'.$doc.'_START__'."\n";<br />
　　　　　　while(&lt;FILE&gt;){<br />
　　　　　　　print $_;<br />
　　　　　　}<br />
　　　　　　print '__FILE_'.$doc.'_END__'."\n".;<br />
　　　　　close(FILE);<br />
　　　　}<br />
　　　}<br />
　　　else{<br />
　　　　next;<br />
　　　}<br />
　　}<br />
　　print '__DIR_'.$dir.'_END__'."\n";<br />
　closedir($dh);<br />
}<br />
<br />
exit;<br />
<br />
-----------------------------------------------------------------------------------------<br />
<br />
※perl5.6以降だと、ループの度にディレクトリハンドル（上で言う$dh）を自動生成してくれる。そうじゃないと一回目でclosedirされて多分ループが続かない。<br />
※ヘッダ出力はお好きなように。<br />
※使い道・・・・・多分ほとんどない。<br />
　ダウンロードしたりLWP転送するときも、tar.gzとかzipにして一発出力したほうが手っ取り早いから・・・<br />
　圧縮展開が面倒くさくて、ファイルも少量のときくらいはこれでやってもいいと思うけど。<br />
]]>
        
    </content>
</entry>

<entry>
    <title>HTML(XHTML)のreadonly属性とdisabled属性の違い</title>
    <link rel="alternate" type="text/html" href="http://www.igreks.jp/dev/2009/11/htmlxhtmlreadonlydisabled.html" />
    <id>tag:www.igreks.jp,2009:/dev//1.418</id>

    <published>2009-11-06T04:49:23Z</published>
    <updated>2010-02-14T10:27:16Z</updated>

    <summary><![CDATA[今更基本的なことだが、form部品の中に、 例えば &lt;input type...]]></summary>
    <author>
        <name>管理人</name>
        
    </author>
    
        <category term="HTML" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="MilkyStep" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="http://www.igreks.jp/dev/">
        <![CDATA[今更基本的なことだが、form部品の中に、<br />
<br />
例えば<br />
<br />
&lt;input type='checkbox' name='cb' value='1' checked disabled&gt;<br />
<br />
とすると、「checked」にしていても、送信先でvalue値が空になってしまうらしい。<br />
（firefoxでしか試してないけど）<br />
<br />
<br />
チェックボックスを空のまま固定するんならいいけど、チェックを入れた状態で固定したいときに保存処理を行うとチェックされてない状態と同じ状態で保存されてしまうので困る。<br />
<br />
そしたら「readonly」というのがあったらしく、disabledの代わりにこれを使ったらよかったらしい。<br />
<br />
&lt;input type='checkbox' name='cb' value='1' checked readonly&gt;<br />
<br />
（XHTMLの場合は、readonly='readonly'とする）<br />
<br />
<br />
だったら「disabled」なんていらねーんじゃねーか？<br />
と思ったんだけど、頭いい人は何かしらのときに使うんだべな。<br />
<br />
<br />
ちなみにIEじゃサポートされて無いって噂なんだが今はダイジョブなのかな？<br />
<br />
<br />
<br />
2010/2/14追記：<br />
<br />
readonlyにすると、テキストフォームなら入力できないが、チェックボックスの場合はチェックができてしまい、値も送信されちゃうので、そういうときは<br />
"checked disabled"にしといて、別にhiddenフィールドでチェックボックスのvalueを送信します。<br />
<br />
&ltform action='' method='post'&gt;<br />
（中略）<br />
&lt;input type='checkbox' name='aaa' value='1' checked disabled&gt;<br />
（中略）<br />
&ltinput type='hidden' name='aaa' value='1'&gt;<br />
&lt/form&gt;<br />
]]>
        
    </content>
</entry>

</feed>
