カレッヂ |
質問者 yaku sima
投稿日 7/20(金) 00:24:53
下のコードは、otherIDがreadableなら真になる条件文のつもりです。 substr(sprintf("%04o",(stat($_))[2] & 07777),3,1) >= 4 otherIDでのpermission checkは、userID、groupIDでのファイルテスト演算子(-r,-w,-x,-o)で行えないので、stat関数で返ってきたモード値をマスクする、こうした形しかないんですかね? ご教授ください。 |
回答者 呑兵衛
[削除]
投稿日 7/20(金) 18:28:12
呑兵衛です。先日はどうも。 そんな難しく考えないで、 各ファイルに対して open 関数で読み込み可能なら真、 という風に持っていけば良いのでは。 この場合、other のパーミッションが ---、-w-、-wx、--x はすべて偽が返りますよね。 |
質問者 yaku sima
[削除]
投稿日 7/21(土) 01:07:21
またまた、お世話になります。 質問が言足らずでした。m(__)m コードも足らなかったようです。 こんな感じでファイル名を展開して、以前のソートをするわけでして、(また、mapしてます。(^_^;) my $omode=4; my $ar; push_array{ map{ substr(sprintf("%04o",(stat($_))[2] & 07777),3,1) >= $omode and -d $_ ? push_array($_) : push(@$ar,$_) }glob($_[0]."/*"); } push_array("./tmp"); と大量のファイル名を扱うのでいちいちファイルをopenするのはどうかと。closeしなくてはならないし、permissionがreadableだけとは限らないようにするので。 |
回答者 呑兵衛
[削除]
投稿日 7/21(土) 17:37:06
全体のコーディングが変わるかもしれませんが、 あるディレクトリ($dir)以下を grep(/^[-dl]/, (`ls -lR $dir`)); で引っ張ってきて drwxr-xr-x 1 nonbei nonbeigrp 70295 Jul 20 02:26 www_html -rwxr-xr-x 1 nonbei nonbeigrp 53294 Jul 20 02:26 hoge.cgi -rw-r--r-- 1 nonbei nonbeigrp 2286 Jul 20 02:26 hoge_1.dat -rw------- 1 nonbei nonbeigrp 802 Jul 20 04:34 hoge_2.dat -rw-r--r-- 1 nonbei nonbeigrp 11807 Jul 20 19:30 foo.cgi パーミッション値の部分を選別し index $_ , 'r', 7; drwxr-xr-x 1 nonbei nonbeigrp 70295 Jul 20 02:26 www_html -rwxr-xr-x 1 nonbei nonbeigrp 53294 Jul 20 02:26 hoge.cgi -rw-r--r-- 1 nonbei nonbeigrp 2286 Jul 20 02:26 hoge_1.dat -rw-r--r-- 1 nonbei nonbeigrp 11807 Jul 20 19:30 foo.cgi 必要な文字列(ファイル名)だけ取り出し、 $_ =~ s/.*\s//g; (場合によってはディレクトリ名をリスト名に) '@' .= $_ !~ /\./); www_html hoge.cgi hoge_1.dat foo.cgi リストにぶち込む、 push(@www_html, $_); という方法もあるような・・・。 map は自分で書いてくだされ。 |
質問者 yaku sima
[削除]
投稿日 7/22(日) 06:21:14
こういうやりかたもあったんですね。思い付きませんでした。 shellコマンドでのls -lRですか。何か邪道ですね。(笑) しっかし、ディレクトリを付けてファイル名を取り出すのは、けっこう面倒ですね。挫折しました。うまく取り出せたら教えて。 コードはこんな感じです。 my @ar=grep{(index $_->[0],'r',7)>0}map{my($a,$b)=(split /\s+/,$_)[0,8];[$a,$b]}grep{/^[-d]/}`ls -lR pds`; for(0..$#ar){print "mode = $ar[$_]->[0] fname = $ar[$_]->[1]\n";} どちらかというと、pure perlがわたしは好きなんですけど、これからどうもうまくいかない時shellコマンドっていう最後の選択も考えておきます。 またまた、以前のコードに致命的な欠陥がありました。パーミッションチェックです。コードを見て比較してみて。 あまりに不細工(結構速いが)だったので、修正さしてください。m(__)m 基本的に同じですが、File::Findを使った関数にしました。実行効率を犠牲に分りやすさを重視しました。 use File::Find; my $ar; my $mode={ 'r'=>[4,5,6,7], 'w'=>[2,3,6,7], 'x'=>[1,3,5,7] }; my $ugo=[1,2,3]; sub permchk{grep{$_[0] == $omode->{$_[1]}->[$_]}0..3} sub push_array{ !-d and !-l and permchk(substr(sprintf("%04o",(stat($_))[2] & 0777),$ugo->[2],1),'r') and push(@$ar,$File::Find::name); } find(\&push_array,'tmp'); 余談ですが、Benchmarkするとこうなりました。 reflexはglobでの再帰で、filefindはその名のとおりモジュールを使ったもので、shellは、コマンドlsを使ったものです。 Benchmark: timing 1000 iterations of filefind, reflex, shell... filefind: 12 wallclock secs ( 6.57 usr 2.71 sys + 1.77 cusr 1.64 csys = 12.69 CPU) @ 107.76/s (n=1000) reflex: 9 wallclock secs ( 5.51 usr + 2.68 sys = 8.19 CPU) @ 122.10/s (n=1000) shell: 24 wallclock secs ( 6.48 usr 4.97 sys + 7.48 cusr 5.02 csys = 23.95 CPU) @ 87.34/s (n=1000) Rate shell filefind reflex shell 87.3/s -- -19% -28% filefind 108/s 23% -- -12% reflex 122/s 40% 13% -- globが速かったようです。残念ですが、shellはかなり遅かったです。 |
返信(回答)する
Web裏技 |