2008-10-15 6 views

Répondre

61

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

Si vous voulez juste lire un répertoire, ouvrez/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... 
+2

Vérifiez la valeur de retour des commandes système: opendir ... ou mourir "... $!" Ou "utiliser autodie;" pour les rendre fatales par défaut. Je sais que c'est juste un pic, mais quand vous donnez des conseils aux débutants, c'est une leçon importante pour eux. – tsee

+0

Oui, vous avez raison, je vais l'ajouter. Merci. –

+0

Dans le cas où quelqu'un se demande pourquoi readdir et closedir ne sont pas cochés: les deux n'ont qu'une seule erreur possible, 'handle de répertoire invalide'. Depuis que je l'ai ouvert moi-même et vérifié, je peux supposer que c'est valide. De plus, dans le contexte de la liste, readddir ne peut pas être vérifié de toute façon. –

6

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

$listing = `ls`; 

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

0

Je vous recommande de jeter un oeil à IPC::Open3. Il permet un contrôle beaucoup plus important sur le processus engendré que le système ou les backticks.

12

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

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

+0

Plus précisément, glob fait exactement ce que vous voulez: retourne un tableau des noms de fichiers dans un dossier. –

0

Sur Linux, je préfère trouver:

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

Ceci est particulièrement utile si vous ne faites pas que lister le répertoire, mais que vous voulez trouver des fichiers avec certains critères. Comme disons que vous voulez des fichiers modifiés au cours des 2 derniers jours: mon @recentFiles = map {chomp; $ _} 'find $ theDir -maxdepth 1 -type f -mtime -2'; –

5

Encore un autre exemple:

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

EDIT: Whoops! Je pensais que vous vouliez juste une liste des répertoires ... supprimer l'appel 'répertoire' pour faire de ce script ce que vous voulez ...

Jouer avec des handles de fichiers est la mauvaise façon d'y aller à mon avis. Voici un exemple d'utilisation de File :: Find :: Rule pour trouver tous les répertoires dans un répertoire spécifié. Cela peut sembler plus que tuer pour ce que vous faites, mais plus tard, ça peut valoir le coup.

D'abord, ma solution d'une ligne:

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

maintenant une version plus tirée des commentaires. Si vous avez installé File :: Find :: Rule, vous devriez être capable de l'exécuter sans problème. Ne craignez pas le 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

+1 comme File :: Find :: Rule bascule –

6

Utilisez Perl englobement:

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