2011-02-07 5 views
1

Je voudrais stocker le contenu de /etc/passwd dans une structure, donc je peux mettre à jour chaque valeur plus tard, mais je n'arrive pas à comprendre quelle structure utiliser.Comment stocker/etc/passwd dans un hachage ou un tableau?

#!/usr/bin/perl 

use warnings; 
use strict; 

open PASSWD, "/etc/passwd"; 
while(<PASSWD>) { 

    chomp; 
    my @f = split /:/; 

    print "username $f[0]\n"; 
    print "password $f[1]\n"; 
    print "uid  $f[2]\n"; 
    print "gid  $f[3]\n"; 
    print "gecos $f[4]\n"; 
    print "home  $f[5]\n"; 
    print "shell $f[6]\n"; 
    print "--------------------------\n"; 

} 

Je suppose que ce doit être un tableau de hash, où le nom d'utilisateur est la clé, mais je ne peux pas comprendre comment faire cela.

Est-ce que "Array of Hashes of Array" est le chemin à parcourir?

+1

Moins d'amour pour ['getpw *' et ses amis] (http://perldoc.perl.org/perlfunc.html#Fetching-user-and-group-info) chaque année. – daxim

+0

et je ne vois aucune raison évidente pour cela. J'en utilise un au moins une fois par semaine. –

Répondre

3

entreposée dans un hachage avec les noms d'utilisateur comme clés, et le tableau de répartition comme valeur:

my %passwd =(); 

open PASSWD, "/etc/passwd"; 
while(<PASSWD>) { 

    chomp; 
    my @f = split /:/; 
    @{$passwd{$f[0]}} = @f; 
} 
print $passwd{'Sjoerder'}[3]; 
12

Voir Passwd::Unix:

RÉSUMÉ

Passwd::Unix fournit une interface orientée objet abstrait et la fonction des fichiers standards Unix, tels que /etc/passwd, /etc/shadow, /etc/group. Additionnellement ce module fournit un environnement pour tester un nouveau logiciel, sans utiliser des fichiers système critiques /etc

2

La structure de données vous choisissez dépend vraiment de ce que vous voulez faire avec les données. Si vous souhaitez extraire les données pour un utilisateur donné, vous pouvez utiliser un hachage simple où les clés sont des noms d'utilisateur et la valeur d'une clé donnée est une référence à un tableau des valeurs de/etc/passwd:

open PASSWD, '/etc/passwd'; 
my %users; 
while (<PASSWD>) { 
    chomp; 
    next if /^\s*#/; # ignore comments 
    my ($username, @details) = split /:/; 
    $users{$username} = \@details; 
} 

# get values for user 'root' 
my $values = $users{'root'}; 

# print root's home 
print $values->[4]; 

Si vous voulez être en mesure de parcourir tous les utilisateurs et tirer les détails de façon lisible, vous pouvez choisir un tableau de hash, où chacun a représente un utilisateur et a des touches pour nom d'utilisateur, mot de passe, uid etc:

open PASSWD, '/etc/passwd'; 
my @users; 
while (<PASSWD>) { 
    chomp; 
    next if /^\s*#/; # ignore comments 
    my @f = split /:/; 
    my %hash; 
    @hash{'username','password','uid','gid','gecos','home','shell'} = @f; 
    push @users, \%hash; 
} 
for my $user (@users) { 
    print "User $user->{username} has home $user->{home}\n"; 
} 

Espérons que cela vous donne quelques idées!

+0

Je pense qu'un tableau de tableaux serait une meilleure option pour itérer sur les données pour la performance. Et puis pour la lisibilité et la maintenabilité, définissez quelques "constantes", plutôt que de se souvenir des numéros d'index de tableau. Mais votre point est toujours important, nous ne pouvons pas suggérer une structure sans comprendre comment elle sera accessible. – BMitch

+3

@B Mitch: Étant donné la taille du '/ etc/passwd' (généralement quelques dizaines d'utilisateurs (y compris les comptes système) et très rarement plus de quelques centaines), l'optimisation des performances en itérer sur son contenu semble inutile. Optimiser pour la lisibilité ou la fonctionnalité à la place. –

Questions connexes