我试图使用以下内容获取给定目录中的子目录列表:
#!/usr/bin/perl -wT use strict; use warnings; use File::Find::Rule; use Data::Dumper; my @subdirs = File::Find::Rule->maxdepth(1)->directory->relative->in('mydir'); print Dumper(@subdirs);
但是,运行它会得到结果:
Insecure dependency in chdir while running with -T switch
我知道File::Find
有处理污点模式的选项,但我似乎找不到相应的东西File::Find::Rule
.可以做到以上几点吗?我应该使用替代方法列出子目录吗?我是否完全误解了一些我应该了解的关于污点模式的明显事实?
(编辑!)好的,逻辑会建议投入以下内容可行:
->extras( {untaint => 1, untaint_pattern => $untaint_pattern, untaint_skip => 1} )
这允许您通过将参数直接传递给该模块的find()
函数来使用File :: Find的污点模式功能.顺便提一下,File :: Find提到应该$untaint_pattern
使用qr//
运算符来设置.例如,默认值为
$untaint_pattern = qr|^([-+@\w./]+)$|
但是,这不起作用!实际上,您的问题是File :: Find :: Rule中的已知错误.(例如,这里是CPAN和Debian错误报告.)如果您想要一个错误修正,那么这两个错误报告都有补丁.
如果您处于受限制的环境中,您可以做的一件事就是在代码中自己实现补丁.例如,如果要将所有内容保存在一个文件中,可以在下面添加下面的大代码块use File::Find::Rule
.请注意,这是一个非常快速的修复,可能不是最理想的.如果它不适合您(例如,因为文件名中有空格),请更改使用的模式qr|^([-+@\w./]+)$|
.
最后请注意,如果您希望您的代码组织更好一些,您可能希望将其转储到一个单独的包中,可能称为MyFileFindRuleFix或其他类似的东西,它总是use
在您File::Find::Rule
自己之后.
package File::Find::Rule; no warnings qw(redefine); sub in { my $self = _force_object shift; my @found; my $fragment = $self->_compile( $self->{subs} ); my @subs = @{ $self->{subs} }; warn "relative mode handed multiple paths - that's a bit silly\n" if $self->{relative} && @_ > 1; my $topdir; my $code = 'sub { (my $path = $File::Find::name) =~ s#^(?:\./+)+##; $path = "." if ($path eq ""); # See Debian bug #329377 my @args = ($_, $File::Find::dir, $path); my $maxdepth = $self->{maxdepth}; my $mindepth = $self->{mindepth}; my $relative = $self->{relative}; # figure out the relative path and depth my $relpath = $File::Find::name; $relpath =~ s{^\Q$topdir\E/?}{}; my $depth = scalar File::Spec->splitdir($relpath); #print "name: \'$File::Find::name\' "; #print "relpath: \'$relpath\' depth: $depth relative: $relative\n"; defined $maxdepth && $depth >= $maxdepth and $File::Find::prune = 1; defined $mindepth && $depth < $mindepth and return; #print "Testing \'$_\'\n"; my $discarded; return unless ' . $fragment . '; return if $discarded; if ($relative) { push @found, $relpath if $relpath ne ""; } else { push @found, $path; } }'; #use Data::Dumper; #print Dumper \@subs; #warn "Compiled sub: '$code'\n"; my $sub = eval "$code" or die "compile error '$code' $@"; my $cwd = getcwd; # Untaint it if ( $cwd =~ qr|^([-+@\w./]+)$| ) { $cwd = $1; } else { die "Couldn't untaint \$cwd: [$cwd]"; } for my $path (@_) { # $topdir is used for relative and maxdepth $topdir = $path; # slice off the trailing slash if there is one (the # maxdepth/mindepth code is fussy) $topdir =~ s{/?$}{} unless $topdir eq '/'; $self->_call_find( { %{ $self->{extras} }, wanted => $sub }, $path ); } chdir $cwd; return @found; } use warnings; package main;