web-dev-qa-db-fra.com

Comment obtenir une liste de répertoires en Perl?

Je voudrais exécuter ls dans un programme Perl dans le cadre d'un script CGI. Pour cela, j'ai utilisé exec(ls), mais cela ne revient pas de l'appel exec.

Existe-t-il un meilleur moyen d'obtenir la liste d'un répertoire en Perl?

28
user28280

Exec ne revient pas du tout. Si vous le vouliez, utilisez le système.

Si vous voulez simplement lire un répertoire, open/read/close-dir peut être plus approprié.

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

Tout le monde semble coincé sur la partie exécutive de la question.

Si vous voulez une liste de répertoires, utilisez le glob ou opendir intégré à Perl. Vous n'avez pas besoin d'un processus séparé.

12
brian d foy

exec ne redonne pas le contrôle au programme Perl. le système le fera, mais il ne retourne pas les résultats d'un ls, il renvoie un code d'état. les graduations `` vous donneront la sortie de notre commande, mais sont considérées par certains comme dangereuses.

Utilisez les fonctions dir intégrées. opendir, readdir, etc.

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

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

8
J.J.

Pour obtenir la sortie d'une commande système, vous devez utiliser des raccourcis.

$listing = `ls`;

Cependant, Perl est bon pour gérer les répertoires pour lui-même. Je recommanderais d'utiliser File :: Find :: Rule.

6
holli

Utilisez Perl Globbing:

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

Encore un autre exemple:

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

EDIT: Oups! Je pensais que vous vouliez juste une liste des répertoires ... supprimez l'appel 'directory' pour que ce script fasse ce que vous voulez ...

À mon avis, jouer avec des descripteurs de fichiers est la mauvaise façon de procéder. Voici un exemple d'utilisation de File :: Find :: Rule pour rechercher tous les répertoires dans un répertoire spécifié. Cela peut sembler excessif pour ce que vous faites, mais plus tard, cela en vaut la peine.

Tout d'abord, ma solution en une seule ligne:

File::Find::Rule->maxdepth(1)->directory->in($base_dir);

Maintenant, une version plus élaborée avec des commentaires. Si File :: Find :: Rule est installé, vous devriez pouvoir l'exécuter sans problème. N'ayez pas peur du 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);
5
Octoberdan

Je vous recommande de jeter un œil à IPC :: Open . Il permet de contrôler beaucoup plus le processus généré que le système ou les astuces.

0
dsm

Sous Linux, je préfère trouver:

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