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

29
我希望在Perl程序中作为CGI脚本的一部分执行ls。我使用了exec(ls),但这不会从exec调用返回。

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


system("ls"); 就会执行这个操作。 - access_granted
9个回答

66

Exec不会返回任何内容。如果你需要返回内容,可以使用system。

如果你只想读取一个目录,可以使用open/read/close-dir。

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

2
检查系统命令的返回值:opendir...或者 die "... $!"。或者使用 "use autodie;" 使其默认为致命错误。我知道这只是一个小细节,但对于给初学者的建议而言,这是一个重要的教训。 - tsee
如果有人想知道为什么没有检查readdir和closedir:它们只有一个可能的错误,即“无效的目录句柄”。由于我自己打开并检查了它,我可以安全地假设它是有效的。而且,在列表上下文中,readdir也无法被检查。 - Leon Timmermans
1
如果您不想要点文件,则可以执行以下操作: my @files = grep { !/^./ } readdir $dh; - Ranguard
9
如果你想要以点开头的文件,但不包括 ...(代表当前目录和父目录),那么你需要使用以下代码:my @files = grep { !/^\.\.?$/ } readdir $dh; - Platinum Azure

12

其他人似乎都卡在 exec 部分的问题上。

如果您想要一个目录列表,请使用 Perl 内置的 globopendir。 您不需要单独的进程。


具体来说,glob 正好做你想要的事情:返回文件夹中文件名称的数组。 - Robert P

8

6

使用Perl通配符:

my $dir = </dir/path/*> 

6
另一个例子:
chdir $dir or die "Cannot chroot to $dir: $!\n";
my @files = glob("*.txt");

6
为了获取系统命令的输出,您需要使用反引号。
$listing = `ls`;

然而,Perl在处理自身的目录方面表现很好。我建议使用File::Find::Rule。


5

编辑:糟糕!我以为你只是想要列出目录...删除“directory”调用,使此脚本按照你的要求执行...

在我看来,玩弄文件句柄是错误的方法。以下是使用File::Find::Rule查找指定目录中所有目录的示例。对于你正在做的事情来说,这可能看起来有点过度,但在后面的过程中它可能很值得。

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

File::Find::Rule->maxdepth(1)->directory->in($base_dir);

现在是带有注释的更详细版本。如果您安装了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);

0
我建议您查看IPC::Open3。它比system或反引号更能控制生成的进程。

0

在Linux上,我更喜欢使用find命令:

my @files = map { chomp; $_ } `find`;

这在编程中非常有用,特别是当你不仅仅是列出目录,而是想要按某些条件查找文件时。比如说,你想要查找最近2天修改过的文件:my @recentFiles = map { chomp; $_ } find $theDir -maxdepth 1 -type f -mtime -2; - Michael Rush

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接