【发布时间】:2010-09-17 08:05:19
【问题描述】:
我想在 Perl 程序中执行 ls 作为 CGI 脚本的一部分。为此,我使用了exec(ls),但这不会从exec 调用中返回。
有没有更好的方法在 Perl 中获取目录列表?
【问题讨论】:
-
系统(“ls”);会这样做。
我想在 Perl 程序中执行 ls 作为 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...
【讨论】:
. 和..(对于当前目录和父目录),那么你想要:my @files = grep { !/^\.\.?$/ } readdir $dh;。
其他人似乎都停留在问题的执行部分。
如果您想要目录列表,请使用 Perl 的内置 glob 或 opendir。您不需要单独的流程。
【讨论】:
exec 不会将控制权交还给 perl 程序。 system 会,但它不返回 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);
现在是带有 cmets 的更详细的版本。如果你安装了 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`;
【讨论】:
find $theDir -maxdepth 1 -type f -mtime -2;