




Чтобы получить вывод системной команды, вам нужно использовать обратные кавычки.
$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 "... $!" Или «использовать автоделку»; чтобы сделать их смертельными по умолчанию. Я знаю, что это просто придирка, но когда вы даете совет новичкам, это важный урок для них.
На случай, если кому-то интересно, почему readdir и closedir не проверяются: у обоих есть только одна возможная ошибка, «недопустимый дескриптор каталога». Поскольку я сам открыл его и проверил, могу с уверенностью предположить, что он действительный. Кроме того, в контексте списка readddir все равно не может быть проверен.
Если вам НЕ нужны точечные файлы, вы можете сделать это: my @files = grep {! / ^ \ ./} readdir $ dh;
Если вам нужны файлы, начинающиеся с точки, но не . и .. (для текущего и родительского каталога), тогда вам нужно: my @files = grep { !/^\.\.?$/ } readdir $dh;.
exec не возвращает управление программе Perl. система будет, но он не возвращает результаты ls, он возвращает код состояния. галочки `` дадут вам результат нашей команды, но некоторые считают его небезопасным.
Используйте встроенные функции dir. opendir, readdir и так далее.
Я бы порекомендовал вам взглянуть на IPC :: Open3. Он обеспечивает гораздо больший контроль над порожденным процессом, чем система или обратные кавычки.
Все остальные, кажется, застряли в части вопроса, посвященной руководству.
Если вам нужен список каталогов, используйте встроенные в Perl glob или opendir. Вам не нужен отдельный процесс.
В частности, glob делает именно то, что вы хотите: возвращает массив имен файлов в папке.
В Linux я предпочитаю найти:
my @files = map { chomp; $_ } `find`;
это особенно полезно, если вы не просто перечисляете каталог, но хотите найти файлы по некоторым критериям. Например, вы хотите, чтобы файлы были изменены за последние 2 дня: my @recentFiles = map {chomp; $ _} find $theDir -maxdepth 1 -type f -mtime -2;
Еще один пример:
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 качается
Используйте Perl Globbing:
my $dir = </dir/path/*>
система ("LS"); сделал бы именно это.