別案件のお手伝い中で DBM を使ったんだけど、ハマったのでネタにしてみる。
今回やりたいのは、DBM ファイルの内容を確認すること。システム(CGI)でそういう処理をしている箇所があったので、とりあえずそれを真似してみた。
perl -MData::Dumper -e 'dbmopen(%data, $ARGV[0], 0666); print Dumper(\%data); dbmclose %data;' hoge.dbm
これでそれっぽい内容は拾えてるんだけど、なんだか文字化けしてしまう。「DBM 内部に格納されているデータの文字コードが想定と違うのかな?」といろいろ試したけど、すべてはずれ。
その後数時間いろいろ試したんだけど、解決せず。その案件のメイン担当の人に聞いてみると、この CGI 経由で見るとちゃんと文字化けせずに表示されてるそうで。
環境まわりが怪しいんなら・・・と、あてずっぽうで
env LANG=C perl -MData::Dumper -e 'dbmopen(%data, $ARGV[0], 0666); print Dumper(\%data); dbmclose %data;' hoge.dbm
と環境変数の LANG を変更したら、文字化けしなくなった。もともとの LANG は en_US.UTF-8 に設定されていて、ja_JP.UTF-8 の場合も同じく化けるけど、それ以外に設定されている場合は化けないらしい。
ちなみに Perl 側で
$ENV{LANG} = "C"
みたいにやって環境変数を設定した場合は改善せず。dbmopen() とかが組み込みのモジュールなのと関係あるのかな?と思ったけど、GDBM_File モジュールを使っても同じだったし、そういうわけでもないらしい。何がなにやら。
とりあえず今度からなんだかわからないハマり方したら、
env - 〜
で環境変数を初期化して実行する癖をつけよう。
いろいろ調べてて学んだこと
文字コード判別
たいていの場合は化け方で判断つくんだけど、今回はさっぱりわからなかったので判別方法を調べてみた。
nkf --guess
でできるらしい。他にも kcc とかいうコマンドがあったりなかったり。
DBM の種別を調べる
に載ってた。
file xxxxxx.db
これでわかるんだそうな。