【perlメモ】use bigint時にmkdirでハマった件。
perlで32bitの範囲を超える演算を行なうには
として、64bitに拡張して演算を行います。
で、何にハマったのかというとmkdirです。
ちなみにperl 5.8.8でのお話です。
◆test.pl
#!/usr/bin/perl
rmdir("abc");
#umask(0);
mkdir("abc",0777);
chmod(0777,"abc");
上のコードは、ディレクトリを作成するスクリプトです。
rmdirはディレクトリの削除で、削除してから
mkdirで指定した名前のディレクトリを作成しています。パーミッションは0777です。
chmodしているのは、mkdirで指定したとおりにパーミションが設定されることは稀なので、chmodでパーミッション(許可属性)を0777に設定しています。
または、mkdirの前にumask(0)をすれば、指定どおりのパーミッションでディレクトリを作成することができます。
drwxrwxrwx 2 kumacchi kumacchi 4096 4月 24 00:35 abc
実際に作成してみると上の様にディレクトリが作成されます。
rwx rwx rwxでちゃんと0777にパーミッションが設定されています。
#!/usr/bin/perl
use bigint;
rmdir("abc");
#umask(0);
mkdir("abc",0777);
chmod(0777,"abc");
ところが上の様にuse bigintした場合に、このスクリプトを実行すると以下のようになります。
dr—-x–t 2 kumacchi kumacchi 4096 4月 24 00:37 abc
パーミッションがめちゃくちゃです。これが最初bigintのせいだとわからなくて数時間ハマりました。suexecの設定見なおしたり、mkdirの使い方がおかしいのかと調べまわったりしていました。そのうちモジュールが悪さしているのかもと思い、このようなシンプルなサンプルを作ってみたところ普通にディレクトリが作成できるので、モジュールのせいだと分かり切り分けていくうちにbigintだろうと気が付きました。実際にそうでした。
じゃあ、どう指定すればちゃんとパーミッションを指定して、ディレクトリを作成できるのか、又悩みました。基本的に私は勉強が出来ない方なのです。物分かりも悪いし数学とか苦手なのです。
私みたいなタイプは色々ためしてみるしかないので、色々試してみた結果、次の方法だとうまくいくことが分かりました。
#!/usr/bin/perl
use bigint;
rmdir("abc");
#umask(0);
mkdir("abc",511);
chmod(511,"abc");
8進数を使わない。0777は10進数に直すと511です。8進数を電卓で10進数に直してから指定するとうまくいくことが分かりました。
drwxrwxrwx 2 kumacchi kumacchi 4096 4月 24 00:45 abc
これでちゃんと設定できるようになりました。でも、視認性も良くないし、いちいち10進に変換するのもめんどくさいですよね。
◆c.pl
#!/usr/bin/perl
print 0777,"\n";
こんなサンプルを書いてみました。
$ perl c.pl
511
$
実行するとこうなります。
◆c2.pl
#!/usr/bin/perl
use bigint;
print 0777,"\n";
これどうなると思います?
$ perl c2.pl
777
$
こうなりました。あれれー。よくわかんないですけど、前ゼロが消えてそのまま表示されちゃってますね。
つまり8進数が使えないってこと?
#!/usr/bin/perl
rmdir("abc");
#umask(0);
mkdir("abc",777);
chmod(777,"abc");
じゃあつまり、こうなってたってことですか?普通に10進数で777と指定していたのと同じ状態だったということですか?
dr—-x–t 2 kumacchi kumacchi 4096 4月 24 00:56 abc
ビンゴ!。
#!/usr/bin/perl
rmdir("abc");
#umask(0);
mkdir("abc",oct("777"));
chmod(oct("777"),"abc");
そういうわけで、こうしてみました。この方が視認性いいですし。
drwxrwxrwx 2 kumacchi kumacchi 4096 4月 24 01:00 abc
うまくいきました。