まとめて置換

某地方自治体のサイトのリニューアル作業中に運悪く?関係する別の自治体のサイトもリニューアルされた。

リニューアルついでに、リンク先の変更もしようということになったのだが、なんせ5,000ページもあるコンテンツをいちいち手作業でリンク先の変更をするのは大変ということで、ビフォーアフターのタブ区切りテキストを作ってまとめて変換することにした。

さいわい、こちらの方はCMSを使っているのでデータベースのデータをダンプしてそのファイルにたいしてスクリプトを走らすことになった。

というわけで、以下のスクリプトを作った。
やっつけで作ったのだが、こういうのはまたいつか需要があるかもしれないということで。

#!/usr/bin/perl

#
# タブ区切りテキストをベースに置換を行う
#
# 第一引数は変換用のタブ区切りテキスト
# (1列目が変更前、2列目が変更後)
# 第二引数は、変更を適用するテキストファイル
# (SQLなど)
#

$convert = shift @ARGV;
$sql = shift @ARGV;

open(IN, $convert);
my %url;
while(<IN>){
    ($from, $to) = split(/\t/, $_);
    $from =~ s/^\s*(.+)\s*$/\1/;
    $to =~ s/^\s*(.+)\s*$/\1/;
    if(!$from || !$to){
        next;
    }
    $url{$from} = $to;
}
close(IN);

open(DUMP, $sql);
while(<DUMP>){
    $line = $_;
    foreach $from(keys %url){
        $line =~ s/$from/$url{$from}/g;
    }
    print $line;
}
close(DUMP);

exit;

mod_perlを使ってhttpd.confをPerlで動的に生成する

意外と資料が少ないのですが、mod_perlを使用するとhttpd.conf内にPerlスクリプトを記述して、Apacheの起動時に動的にバーチャルホストを定義することができます。

この方法を利用すると、データベースやXMLなどからDocumentRootなどの最小限の情報を取得して、全てのバーチャルホストをテンプレートをベースに構築できますので、効率的で安全なバーチャルホストの設定が行えます。

# 以下をhttpd.conf内等に記述する
<Perl>

use Encode;
use XML::DOM;

my $dom = new XML::DOM::Parser;
my $doc = $dom->parsefile('/home/www/vhost.xml');

my $nodes = $doc->getElementsByTagName ("vhost");
my $httpd_conf = '';

for(my $i=0; $i<$nodes->getLength; $i++){

 my $node = $nodes->item($i);
 my $port = $node->getAttribute('port');
 my $name = $node->getAttribute('name');
 my $path = $node->getAttribute('path');
 my $text = Encode::encode(
        'utf8',
        $node->getFirstChild->getNodeValue()
    );

 if($port && $port != 80){
  $httpd_conf .= "Listen $port\n";
 }else{
  $port = '80';
 }
 $httpd_conf .= "<VirtualHost *:$port>\n";
 $httpd_conf .= "DocumentRoot $path\n";
 $httpd_conf .= "ServerName $name\n";
 $httpd_conf .= "</VirtualHost>\n\n";

}

open(OUT, ">/etc/httpd/conf.d/httpd_conf.cache");
print OUT $httpd_conf;
close(OUT);

$PerlConfig = "Include \"/etc/httpd/conf.d/httpd_conf.cache\"\n";

</Perl>
# httpd.confここまで

上記の例は、弊社内の開発用サーバーで使用しているもので、ポートベース及びネームベースのバーチャルホストをXML(/home/www/vhost.xml)を元に生成しています。

ここで使用されているXMLは、PHPのアプリケーション側でも読み込んで、テストサーバーのリンク集を生成するのにも利用されています。

したがって、「おーい、例の○○向けのシステムってURLなんだっけ?」みたいなやりとりを減らす効果もあります。

XMLのサンプルは以下の通り。

<?xml version="1.0" encoding="UTF-8" ?>
<vhosts>
  <vhost name="10.0.0.5" port="8003" path="/home/www.example.com/html">
    www.example.com向けECサイト
  </vhost>
</vhosts>

ちなみに、Apacheの1.3系と2.x系では記述内容が違います。
今回紹介している例は2.x系でのサンプルですが、2.X系ではセキュリティ上の制限が加わっているらしく設定できる項目に制限があるようでした。(詳細は勉強不足で不明です。)

それを回避するために、httpd_conf.cacheというファイルに一度書き出して、それをincludeするという方法をとっています。

この例は外部に全く公開していないテストサーバーでの事例なので、セキュリティについては多少目をつぶっています。

というわけで、器用貧乏な弊社ではLinuxサーバー構築のお問い合せをお待ちしています。