我想ls
在 Perl 程序中作为 CGI 脚本的一部分执行。为此,我使用exec(ls)
了 ,但这不会从exec
通话中返回。
有没有更好的方法来获取 Perl 中的目录列表?
Exec 根本不返回。如果你想要那个,使用系统。
如果你只是想读取一个目录,open/read/close-dir 可能更合适。
opendir my($dh), $dirname or die "Couldn't open dir '$dirname': $!";
my @files = readdir $dh;
closedir $dh;
#print files...
其他人似乎都停留在问题的执行部分。
如果您想要目录列表,请使用 Perl 的内置glob
或opendir
. 您不需要单独的过程。
exec不会将控制权交还给 perl 程序。 系统会,但它不返回 ls 的结果,它返回一个状态码。刻度线``会给你我们命令的输出,但被一些人认为是不安全的。
使用内置的 dir 函数。opendir、readdir 等。
为了获得系统命令的输出,您需要使用反引号。
$listing = `ls`;
然而,Perl 擅长自己处理目录。我建议使用 File::Find::Rule。
使用 Perl 通配符:
my $dir = </dir/path/*>
还有一个例子:
chdir $dir or die "Cannot chroot to $dir: $!\n";
my @files = glob("*.txt");
编辑:哎呀!我以为您只是想要目录列表...删除“目录”调用以使该脚本执行您想要的操作...
在我看来,使用文件句柄是错误的做法。以下是使用 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);
我建议你看看IPC::Open3。与系统或反引号相比,它允许对生成的进程进行更多的控制。
在 Linux 上,我更喜欢 find:
my @files = map { chomp; $_ } `find`;