Я хотел бы выполнить ls в Perl-программе как часть CGI script. Для этого я использовал exec(ls), но это не возвращается из вызова exec.
Есть ли лучший способ получить список каталогов в Perl?
Я хотел бы выполнить ls в Perl-программе как часть CGI script. Для этого я использовал 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...
Все остальные, кажется, застревают в части exec вопроса.
Если вам нужен список каталогов, используйте Perl встроенный glob или opendir. Вам не нужен отдельный процесс.
exec не возвращает управление программе perl. система, но она не возвращает результаты ls, она возвращает код состояния. отметки метки `` предоставят вам выход нашей команды, но некоторые считают небезопасным.
Используйте встроенные функции dir. opendir, readdir и т.д.
Чтобы получить вывод системной команды, вам нужно использовать обратные ссылки.
$listing = `ls`;
Однако, Perl хорошо справляется с каталогами для себя. Я бы рекомендовал использовать File:: Find:: Rule.
Использование Perl Globbing:
my $dir = </dir/path/*>
Еще один пример:
chdir $dir or die "Cannot chroot to $dir: $!\n";
my @files = glob("*.txt");
РЕДАКТОР: Упс! Я думал, что вам просто нужен список каталогов... удалите вызов "directory", чтобы сделать этот script делать то, что вы хотите...
Игра с файловыми дескрипторами - неправильный путь, по моему мнению. Ниже приведен пример использования 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 я предпочитаю находить:
my @files = map { chomp; $_ } `find`;