apache httpd 2.4 の新機能 mod_sed を試します。ドキュメントで示されている例は単純なのでもう少し複雑なもので調べてみます。
sed を知るために、ここでは以下を参考にします。
http://www.bookshelf.jp/texi/sed/sed-ja.html#SEC_Top
重要なのは、「3.1 sed が動作する様子」です。自分用にまとめてみます。
それによると、sed 動作は、次のサイクルを行ごとに繰り返します。
・1行読み込み改行文字を削除して「パターン空間に配置」する。
・アドレスに合致したら、パターン空間の文字列に対してコマンドを実行
・全てのコマンドが終了したら、
指示がない限りパターン空間の内容を出力して、
指示がない限り改行文字を出力する。
・パターン空間の内容を削除し、最初に戻る。
これに加えてサイクル間でデータを保持できるホールド空間があり、パターン空間とデータをやり取りする特殊なコマンドが用意されています。
以上の点から、sed スクリプトは複数行のコマンドからなるプログラムにすることが可能であり、当然のように mod_sed も複数行のスクリプトを受け付けるようになっています。それがどこまで可能なのかを探ってみます。
例えば、
<pre>
........
</pre>
の、....... の部分だけを行の文字を反転する(4.5章参照)ことにするために sed スクリプトを次のようにしたとします。fedora14 の GNU sed ver. 4.2.1 では一応動作します。
これを 設定ファイル httpd.conf に組み込んでみます。mod_sed の説明にしたがいます。今回は、OutputSed ディレクティブを使います。これに指定するには上のスクリプトを1行づつ順番に指定していくようです。
このような後で変更の可能性があるものは、httpd.confに直接指定しないで以下のものを追加にして、今後は httpd-sed-scripts.conf を修正することにします。
LoadModule sed_module modules/mod_sed.so
Include /usr/local/httpd242/conf/extra/httpd-sed-scripts.conf
httpd-sed-scripts.conf は、説明どおりに mod_sed 用のディレクティブを指定します。
しかし、これは httpd を再起動すると次のエラーになります。
Failed to compile sed expression. unrecognized command: /pre>/! {
つまり、sedスクリプトの構文エラーは、httpd の起動時にチェックされるようです。ちなみにエラーが2つある場合は、最初のエラーのある行を直すと、次の行でエラーがでます。
アドレスの中の ! がエラーになっているようです。どうやら完全に sed コマンドと互換性が取れているわけではないようです。
さらにやっかいなのは既存の sed スクリプトの修正です。
もし OutputSed や InputSed を修正しても、指定ディレクトリ以下のファイルが更新されないと、httpd は 304 をブラウザに返します。ブラウザはアクセスしようとしたファイルが更新されてないとして、自分のキャッシュを使って表示されるので修正が反映されません。
またマニュアルには、.htaccess に指定できるようになっていますが、試してみると、
[core:alert] ...省略... /usr/local/httpd242/htdocs/sed/.htaccess: OutputSed not allowed here
のようなエラーになって error_log に出力され、500で戻ってきて使えませんでした。
現在のところ上の sed スクリプトはまだ動作していません。時間があれば、どこが問題かを調べてみたいと思います。
sed を知るために、ここでは以下を参考にします。
http://www.bookshelf.jp/texi/sed/sed-ja.html#SEC_Top
重要なのは、「3.1 sed が動作する様子」です。自分用にまとめてみます。
それによると、sed 動作は、次のサイクルを行ごとに繰り返します。
・1行読み込み改行文字を削除して「パターン空間に配置」する。
・アドレスに合致したら、パターン空間の文字列に対してコマンドを実行
・全てのコマンドが終了したら、
指示がない限りパターン空間の内容を出力して、
指示がない限り改行文字を出力する。
・パターン空間の内容を削除し、最初に戻る。
これに加えてサイクル間でデータを保持できるホールド空間があり、パターン空間とデータをやり取りする特殊なコマンドが用意されています。
以上の点から、sed スクリプトは複数行のコマンドからなるプログラムにすることが可能であり、当然のように mod_sed も複数行のスクリプトを受け付けるようになっています。それがどこまで可能なのかを探ってみます。
例えば、
<pre>
........
</pre>
の、....... の部分だけを行の文字を反転する(4.5章参照)ことにするために sed スクリプトを次のようにしたとします。fedora14 の GNU sed ver. 4.2.1 では一応動作します。
/<pre>/,/<\/pre>/ { /pre>/! { /../! b s/^.*$/\n&\n/ t loop :loop s/\(\n.\)\(.*\)\(.\n\)/¥3¥2¥1/ t loop s/\n//g s/^\(.*[^ ]\)\( *\)$/¥2¥1/ } }
これを 設定ファイル httpd.conf に組み込んでみます。mod_sed の説明にしたがいます。今回は、OutputSed ディレクティブを使います。これに指定するには上のスクリプトを1行づつ順番に指定していくようです。
このような後で変更の可能性があるものは、httpd.confに直接指定しないで以下のものを追加にして、今後は httpd-sed-scripts.conf を修正することにします。
LoadModule sed_module modules/mod_sed.so
Include /usr/local/httpd242/conf/extra/httpd-sed-scripts.conf
httpd-sed-scripts.conf は、説明どおりに mod_sed 用のディレクティブを指定します。
<Directory "/usr/local/httpd242/htdocs/sed">
AddOutputFilter Sed html
OutputSed "/<pre>/,/<\/pre>/ {"
OutputSed "/pre>/! {"
............................
OutputSed "}"
</Directory>
しかし、これは httpd を再起動すると次のエラーになります。
Failed to compile sed expression. unrecognized command: /pre>/! {
つまり、sedスクリプトの構文エラーは、httpd の起動時にチェックされるようです。ちなみにエラーが2つある場合は、最初のエラーのある行を直すと、次の行でエラーがでます。
アドレスの中の ! がエラーになっているようです。どうやら完全に sed コマンドと互換性が取れているわけではないようです。
さらにやっかいなのは既存の sed スクリプトの修正です。
もし OutputSed や InputSed を修正しても、指定ディレクトリ以下のファイルが更新されないと、httpd は 304 をブラウザに返します。ブラウザはアクセスしようとしたファイルが更新されてないとして、自分のキャッシュを使って表示されるので修正が反映されません。
またマニュアルには、.htaccess に指定できるようになっていますが、試してみると、
[core:alert] ...省略... /usr/local/httpd242/htdocs/sed/.htaccess: OutputSed not allowed here
のようなエラーになって error_log に出力され、500で戻ってきて使えませんでした。
現在のところ上の sed スクリプトはまだ動作していません。時間があれば、どこが問題かを調べてみたいと思います。
※コメント投稿者のブログIDはブログ作成者のみに通知されます