我想在Perl程序中执行ls
作为CGI脚本的一部分。为此,我使用了exec(ls)
,但这不会从exec
调用返回。
有没有更好的方法来获取Perl中的目录列表?
答案 0 :(得分:65)
Exec完全没有返回。如果你想要,请使用system。
如果您只想阅读目录,打开/读取/关闭目录可能更合适。
opendir my($dh), $dirname or die "Couldn't open dir '$dirname': $!";
my @files = readdir $dh;
closedir $dh;
#print files...
答案 1 :(得分:12)
其他人似乎都被困在问题的执行部分。
如果您需要目录列表,请使用Perl的内置glob
或opendir
。您不需要单独的流程。
答案 2 :(得分:8)
exec 不会将控制权交还给perl程序。 系统会,但它不会返回ls的结果,它会返回状态代码。 刻度线``将为您提供我们命令的输出,但有些人认为它是不安全的。
使用内置的dir函数。 opendir,readdir等等。
答案 3 :(得分:6)
为了获得系统命令的输出,您需要使用反引号。
$listing = `ls`;
然而,Perl善于处理自己的目录。我建议使用File :: Find :: Rule。
答案 4 :(得分:6)
使用Perl Globbing:
my $dir = </dir/path/*>
答案 5 :(得分:5)
又一个例子:
chdir $dir or die "Cannot chroot to $dir: $!\n";
my @files = glob("*.txt");
答案 6 :(得分: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);
答案 7 :(得分:0)
我建议您查看IPC::Open3。与系统或反引号相比,它允许对生成的进程进行更多控制。
答案 8 :(得分:0)
在Linux上,我更喜欢find:
my @files = map { chomp; $_ } `find`;