如何在Perl中获取目录列表?

use*_*280 28 directory perl list

我想ls在Perl程序中执行作为CGI脚本的一部分.为此,我使用了exec(ls),但这不会从exec通话中返回.

有没有更好的方法来获取Perl中的目录列表?

Leo*_*ans 65

Exec完全没有返回.如果你想要,请使用系统.

如果您只想阅读目录,open/read/close-dir可能更合适.

opendir my($dh), $dirname or die "Couldn't open dir '$dirname': $!";
my @files = readdir $dh;
closedir $dh;
#print files...
Run Code Online (Sandbox Code Playgroud)

  • 如果你想要以dot开头的文件,而不是`.`和`..`(对于当前和父目录),那么你想要:`my @files = grep {!/ ^ \.\.?$ /} readdir $ DH;`. (9认同)
  • 检查系统命令的返回值:opendir ...或死"... $!" 或者"使用autodie;" 使他们默认致命.我知道这只是一个挑剔,但当你给初学者提供建议时,这对他们来说是一个重要的教训. (2认同)

bri*_*foy 12

其他人似乎都被困在问题的执行部分.

如果您想要目录列表,请使用Perl的内置globopendir.您不需要单独的过程.


J.J*_*.J. 8

exec不会将控制权交还给perl程序. 系统会,但它不返回ls的结果,它返回一个状态代码.刻度线``将为您提供我们命令的输出,但有些人认为它是不安全的.

使用内置的dir函数.opendir,readdir等.

http://perldoc.perl.org/functions/opendir.html

http://perldoc.perl.org/functions/readdir.html


hol*_*lli 6

为了获得系统命令的输出,您需要使用反引号.

$listing = `ls`;
Run Code Online (Sandbox Code Playgroud)

但是,Perl善于处理自己的目录.我建议使用File :: Find :: Rule.


小智 6

使用Perl Globbing:

my $dir = </dir/path/*> 
Run Code Online (Sandbox Code Playgroud)


dyn*_*x60 5

又一个例子:

chdir $dir or die "Cannot chroot to $dir: $!\n";
my @files = glob("*.txt");
Run Code Online (Sandbox Code Playgroud)


Oct*_*dan 5

编辑:哎呀!我以为你只是想要一个目录列表...删除'目录'调用,使这个脚本做你想要的...

在我看来,使用文件句柄是错误的方法.以下是使用File :: Find :: Rule查找指定目录中的所有目录的示例.对你正在做的事情似乎过度杀戮,但后来可能是值得的.

首先,我的一线解决方案:

File::Find::Rule->maxdepth(1)->directory->in($base_dir);
Run Code Online (Sandbox Code Playgroud)

现在是一个带有注释的更抽象的版本.如果你安装了File :: Find :: Rule,你应该可以运行这个没问题.不要害怕CPAN.

#!/usr/bin/perl

use strict;
use warnings;

# See http://search.cpan.org/~rclamp/File-Find-Rule-0.32/README
use File::Find::Rule;

# If a base directory was not past to the script, assume current working director
my $base_dir = shift // '.';
my $find_rule = File::Find::Rule->new;

# Do not descend past the first level
$find_rule->maxdepth(1);

# Only return directories
$find_rule->directory;

# Apply the rule and retrieve the subdirectories
my @sub_dirs = $find_rule->in($base_dir);

# Print out the name of each directory on its own line
print join("\n", @sub_dirs);
Run Code Online (Sandbox Code Playgroud)