Как мне получить список каталогов в Perl?

Я хотел бы выполнить ls в программе Perl как часть сценария CGI. Для этого я использовал exec(ls), но это не возвращается из вызова exec.

Есть ли лучший способ получить список каталога в Perl?

система ("LS"); сделал бы именно это.

access_granted 12.02.2020 23:36
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
28
1
91 359
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

Чтобы получить вывод системной команды, вам нужно использовать обратные кавычки.

$listing = `ls`;

Однако Perl хорошо справляется с каталогами самостоятельно. Я бы рекомендовал использовать File :: Find :: Rule.

Ответ принят как подходящий

Exec вообще не возвращается. Если вы этого хотите, используйте system.

Если вы просто хотите прочитать каталог, более подходящим может быть open / read / close-dir.

opendir my($dh), $dirname or die "Couldn't open dir '$dirname': $!";
my @files = readdir $dh;
closedir $dh;
#print files...

Проверьте возвращаемое значение системных команд: opendir ... or die "... $!" Или «использовать автоделку»; чтобы сделать их смертельными по умолчанию. Я знаю, что это просто придирка, но когда вы даете совет новичкам, это важный урок для них.

tsee 15.10.2008 20:26

На случай, если кому-то интересно, почему readdir и closedir не проверяются: у обоих есть только одна возможная ошибка, «недопустимый дескриптор каталога». Поскольку я сам открыл его и проверил, могу с уверенностью предположить, что он действительный. Кроме того, в контексте списка readddir все равно не может быть проверен.

Leon Timmermans 15.10.2008 21:43

Если вам НЕ нужны точечные файлы, вы можете сделать это: my @files = grep {! / ^ \ ./} readdir $ dh;

Ranguard 17.10.2008 10:26

Если вам нужны файлы, начинающиеся с точки, но не . и .. (для текущего и родительского каталога), тогда вам нужно: my @files = grep { !/^\.\.?$/ } readdir $dh;.

Platinum Azure 11.08.2010 17:35

exec не возвращает управление программе Perl. система будет, но он не возвращает результаты ls, он возвращает код состояния. галочки `` дадут вам результат нашей команды, но некоторые считают его небезопасным.

Используйте встроенные функции dir. opendir, readdir и так далее.

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

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

Я бы порекомендовал вам взглянуть на IPC :: Open3. Он обеспечивает гораздо больший контроль над порожденным процессом, чем система или обратные кавычки.

Все остальные, кажется, застряли в части вопроса, посвященной руководству.

Если вам нужен список каталогов, используйте встроенные в Perl glob или opendir. Вам не нужен отдельный процесс.

В частности, glob делает именно то, что вы хотите: возвращает массив имен файлов в папке.

Robert P 17.10.2008 00:01

В Linux я предпочитаю найти:

my @files = map { chomp; $_ } `find`;

это особенно полезно, если вы не просто перечисляете каталог, но хотите найти файлы по некоторым критериям. Например, вы хотите, чтобы файлы были изменены за последние 2 дня: my @recentFiles = map {chomp; $ _} find $theDir -maxdepth 1 -type f -mtime -2;

Michael Rush 09.03.2012 05:37

Еще один пример:

chdir $dir or die "Cannot chroot to $dir: $!\n";
my @files = glob("*.txt");

Обновлено: Упс! Я думал, вам просто нужен список каталогов ... удалите вызов 'directory', чтобы этот скрипт делал то, что вы хотите ...

На мой взгляд, игра с файловыми дескрипторами - неправильный путь. Ниже приведен пример использования 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);

+1, поскольку File :: Find :: Rule качается

Matthew Lock 03.12.2012 06:17

Используйте Perl Globbing:

my $dir = </dir/path/*> 

Другие вопросы по теме