28

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

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

4

9 回答 9

66

Exec 根本不返回。如果你想要那个,使用系统。

如果你只是想读取一个目录,open/read/close-dir 可能更合适。

opendir my($dh), $dirname or die "Couldn't open dir '$dirname': $!";
my @files = readdir $dh;
closedir $dh;
#print files...
于 2008-10-15T15:28:45.267 回答
12

其他人似乎都停留在问​​题的执行部分。

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

于 2008-10-15T21:49:31.647 回答
8

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

使用内置的 dir 函数。opendir、readdir 等。

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

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

于 2008-10-15T15:31:15.153 回答
6

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

$listing = `ls`;

然而,Perl 擅长自己处理目录。我建议使用 File::Find::Rule。

于 2008-10-15T15:27:39.217 回答
6

使用 Perl 通配符:

my $dir = </dir/path/*> 
于 2011-07-05T18:45:20.870 回答
5

还有一个例子:

chdir $dir or die "Cannot chroot to $dir: $!\n";
my @files = glob("*.txt");
于 2010-07-29T10:29:25.193 回答
5

编辑:哎呀!我以为您只是想要目录列表...删除“目录”调用以使该脚本执行您想要的操作...

在我看来,使用文件句柄是错误的做法。以下是使用 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);
于 2010-08-11T13:31:35.993 回答
0

我建议你看看IPC::Open3。与系统或反引号相比,它允许对生成的进程进行更多的控制。

于 2008-10-15T17:22:53.663 回答
0

在 Linux 上,我更喜欢 find:

my @files = map { chomp; $_ } `find`;
于 2008-10-17T01:30:10.903 回答