我正在尝试使用以下内容获取给定目录中的子目录列表:
#!/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
中的等价物。可以做到以上几点吗?我应该使用替代方法列出子目录吗?我是否完全误解了一些我应该了解的关于污点模式的明显事实?
答案 0 :(得分:5)
(编辑!)好的,逻辑会建议投入以下内容可行:
->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;