miau's blog?

Cwd module

Perl で File::Find を使うことが多いと思うんですが。
Windows 環境で、日本語フォルダを使用している場合で、検索パスに「ソ」とか 2 バイト目が「\」な文字が含まれてる場合、実はうまく処理できてないことに気づきましたので、その対策方法とか。




例えば C:/test/ソース なんてファイルに対して File::find を使おうとすると、こんなエラーが出ます。

Can't cd to C:/test/・ース: No such file or directory

File::Find とか File::Spec とか調べてみたけど、結局問題あるのは Cwd モジュールっぽくて。
Cwd.pm 内で、

sub _win32_cwd {
$ENV{'PWD'} = Win32::GetCwd();
$ENV{'PWD'} =~ s:\\:/:g ;
return $ENV{'PWD'};
}

こんなことやってる。

CWD::_win32_cwd() ってのはその名の通り Windows 特有の処理だけど、Win32::GetCwd() の結果はシステム上の文字コード(日本語版の Windows なら cp932)で取得されるわけで。
cp932 は二文字目に "\\" が入るから、無条件に置換しちゃダメだってば。

そんなわけで、こんな感じに修正。

sub _win32_cwd {
$ENV{'PWD'} = Win32::GetCwd();
use Encode;
my $cp = (`chcp` =~ m/(\d+)/)[0];
if (defined $cp) {
$ENV{'PWD'} = decode("cp$cp", $ENV{'PWD'});
}
$ENV{'PWD'} =~ s:\\:/:g ;
if (defined $cp) {
$ENV{'PWD'} = encode("cp$cp", $ENV{'PWD'});
}
return $ENV{'PWD'};
}

日本語以外のコードページでも 2 バイト目に「\」とか入るか知らないけど、一応汎用性持たせてみました。

・use Encode してしまっている(古い Perl だと動かない)
・毎回呼び出してるので効率悪い
・変換が必要ないコードページの人も変換が入るので、これまた効率悪い

とか問題はあるけど、まぁ気が向いたらちゃんと書きます。


ちなみに Windows XP x64 Edition だと Perl から chcp コマンドが使えなくて焦った。
cmd.exe からなら呼び出せるのに、なんで?

と思ったんだけど、よく見たら C:\Windows\System32 には chcp.exe があるけど、C:\Windows\SysWOW64 にはない状態っぽい。
Perl.exe は 32 bit アプリケーションだから、Perl から見た場合は System32 にパス通ってないわけね・・。
C:\Windows\System32\chcp.exe を C:\Windows\SysWOW64\chcp.exe にコピーすれば OK。


ついでに、C:\Perl\lib\Cwd.pm とかを汚したくない人のために、再定義用の書き方。

use Cwd;
BEGIN {
no warnings 'redefine';

sub Cwd::_win32_cwd {
$ENV{'PWD'} = Win32::GetCwd();
use Encode;
my $cp = (`chcp` =~ m/(\d+)/)[0];
if (defined $cp) {
$ENV{'PWD'} = decode("cp$cp", $ENV{'PWD'});
}
$ENV{'PWD'} =~ s:\\:/:g ;
if (defined $cp) {
$ENV{'PWD'} = encode("cp$cp", $ENV{'PWD'});
}
return $ENV{'PWD'};
}

use warnings 'redefine';

*Cwd::cwd = *Cwd::getcwd = *Cwd::fastcwd = *Cwd::fastgetcwd = *Cwd::_win32_cwd;
}

こんな感じでいいのかな?
posted at 22:18:57 on 2006-03-16 by miau - Category: Perl No Trackbacks - Permalink

TrackBack

このエントリにトラックバックはありません
現在トラックバックは受け付けていません。

Comments

No comments yet

Add Comments

現在コメントは受け付けていません。
お手数ですが、 こちら のコメント欄にでも記載していただければと思います。