OVH Cloud OVH Cloud

problème de n après une regexp ???

3 réponses
Avatar
Pierre-Yves
hello,

J'ai un soucis avec un script que je viens d'écrire et je n'arrive pas a
corriger le problème.
J'essaye d'obtenir le "primary group" d'un utilisateur unix (en utilisant la
commande id)

cette commande retourne ceci :
id myuser
returns uid=12345(myuser) gid=54321(mygroup)

Pour récupérer le groupe, j'ai écris une regexp :
my $pri_grp = `id myuser`;
$pri_grp =~ s/^.+gid=.+\((.+)\)$/$1/;

le problème c'esy que PARFOIS $pri_grp se termine par un retour à la ligne
(\n ?), je ne comprend pas pourquoi. J'ai essayé de faire un chomp sur la
variable mais ca n'arrange rien.

du coup mon code ne fonctionne pas toujours.... j'ai mis une copie
ci-dessous.
Il s'agit d'une fontion récursive, qui récupère le "owner" des dossier
parents et qui ajoute un nouveau groupe à ces utilisateurs.

PS: J'utilise Perl 5.8.2 sur Solaris 5.8



#!/usr/bin/perl

my $parent_vapth = "/dev/thematics/dir1/dir12/dir121/dir1211";
my $th_apth = "/dev/thematics";
my $usr_group = "grp12111";

sub setGroups {
my $br_path = $_[0];
my $th_path = $_[1];
my $usr_grp = $_[2];
my $err_cnt = $_[3];

return false if $br_path !~ m#^${th_path}/.+$#;

# ls -od to get the owner of the directory
my $ls = `ls -od $br_path`;
my @ls = split(/\s+/,$ls);

# find primary group for user (using id)
my $pri_grp = `id $ls[2]`;
chomp($pri_grp); #test
$pri_grp =~ s/^.+gid=.+\((.+)\)$/$1/;
chomp($pri_grp); #test

### HERE I GOT A PROBLEM, IT SEEMS THAT SOMETIMES $pri_grp ENDS WITH
A '\n'
print "DEBUG: primary group is ***${pri_grp}***\n";

# list the groups the user belongs (using groups)
my $grp_lst = `groups $ls[2]`;
chomp($grp_lst);

# exclude the primary group and add the new group
@grp_lst = split(' ',$grp_lst);
$grp_lst = "";

foreach my $curr_grp (@grp_lst) {
next if $curr_grp eq $pri_grp;
$grp_lst .= "${curr_grp},";
}

$grp_lst .= "$usr_grp";

my $rc = system("usermod -G $grp_lst $ls[2]");

if ($rc ne 0) {
print "usermod -G $grp_lst $ls[2] failed. return code is
$rc\n";
}

# go one level up
$br_path =~ m#(.+)/.+$#;
$br_path = $1;

return setGroups($br_path, $th_path, $usr_grp, $err_cnt);
}

setGroups($parent_vpath, $thematics_path, $user_group, 0);

3 réponses

Avatar
Paul Gaborit
À (at) Thu, 16 Sep 2004 09:13:45 +0200,
"Pierre-Yves" <pyu-at-belbone.be> écrivait (wrote):
J'essaye d'obtenir le "primary group" d'un utilisateur unix (en utilisant la
commande id)


Pourquoi ne pas utiliser les fonctions internes de perl ?

Pour récupérer les gid d'un utilisateur (par son nom $login) :

my $gid = (getpwnam($name))[3];

Pour récupérer le nom associé à ce $gid :

my $groupname = (getgrgid($gid))[0];
ou
my $groupname = getgrgid($gid);

Les fonctions 'getpwnam' et 'getgrgid' (et toutes les autres fonctions
similaires) sont décrites de manière générique dans perlfunc :


Ces routines réalisent exactement les mêmes fonctions que leurs homologues
de la bibliothèque système. Dans un contexte de liste, les valeurs
retournées par les différentes routines sont les suivantes :

($name,$passwd,$uid,$gid,
$quota,$comment,$gcos,$dir,$shell,$expire) = getpw*
($name,$passwd,$gid,$members) = getgr*
($name,$aliases,$addrtype,$length,@addrs) = gethost*
($name,$aliases,$addrtype,$net) = getnet*
($name,$aliases,$proto) = getproto*
($name,$aliases,$port,$proto) = getserv*

(Si une entrée n'existe pas, vous récupérerez une liste vide.)

La signification exacte du champ $gcos varie mais contient habituellement
le nom réel de l'utilisateur (au contraire du nom de login) et d'autres
informations pertinentes pour cet utilisateur. Par contre, sachez que sur
de nombreux systèmes, les utilisateurs peuvent changer eux-mêmes ces
informations. Ce n'est donc pas une information de confiance. Par
conséquent $gcos est souillée (voir la page de manuel perlsec). Les champs
$passwd, $shell ainsi que l'interpréteur de commandes (login shell) et le
mot de passe crypté sont aussi souillés pour les mêmes raisons.

Dans un contexte scalaire, vous obtenez le nom sauf lorsque la fonction
fait une recherche par nom auquel cas vous récupérerez autre chose. (Si
une entrée n'existe pas vous récupérerez la valeur undef.) Par exemple :

$uid = getpwnam($name);
$name = getpwuid($num);
$name = getpwent();
$gid = getgrnam($name);
$name = getgrgid($num;
$name = getgrent();
#etc.


--
Paul Gaborit - <http://www.enstimac.fr/~gaborit/>
Perl en français - <http://www.enstimac.fr/Perl/>

Avatar
Pierre-Yves
Merci!

C'est exactement ce qu'il me fallait... je ne connaissais pas ces fonctions
(je connais mieux unix que perl).
Maintenant mon script fonctionne parfaitement :-)


"Paul Gaborit" wrote in message
news:

À (at) Thu, 16 Sep 2004 09:13:45 +0200,
"Pierre-Yves" <pyu-at-belbone.be> écrivait (wrote):
J'essaye d'obtenir le "primary group" d'un utilisateur unix (en
utilisant la


commande id)


Pourquoi ne pas utiliser les fonctions internes de perl ?

Pour récupérer les gid d'un utilisateur (par son nom $login) :

my $gid = (getpwnam($name))[3];

Pour récupérer le nom associé à ce $gid :

my $groupname = (getgrgid($gid))[0];
ou
my $groupname = getgrgid($gid);

Les fonctions 'getpwnam' et 'getgrgid' (et toutes les autres fonctions
similaires) sont décrites de manière générique dans perlfunc :


Ces routines réalisent exactement les mêmes fonctions que leurs
homologues

de la bibliothèque système. Dans un contexte de liste, les valeurs
retournées par les différentes routines sont les suivantes :

($name,$passwd,$uid,$gid,
$quota,$comment,$gcos,$dir,$shell,$expire) = getpw*
($name,$passwd,$gid,$members) = getgr*
($name,$aliases,$addrtype,$length,@addrs) = gethost*
($name,$aliases,$addrtype,$net) = getnet*
($name,$aliases,$proto) = getproto*
($name,$aliases,$port,$proto) = getserv*

(Si une entrée n'existe pas, vous récupérerez une liste vide.)

La signification exacte du champ $gcos varie mais contient
habituellement

le nom réel de l'utilisateur (au contraire du nom de login) et
d'autres

informations pertinentes pour cet utilisateur. Par contre, sachez que
sur

de nombreux systèmes, les utilisateurs peuvent changer eux-mêmes ces
informations. Ce n'est donc pas une information de confiance. Par
conséquent $gcos est souillée (voir la page de manuel perlsec). Les
champs

$passwd, $shell ainsi que l'interpréteur de commandes (login shell) et
le

mot de passe crypté sont aussi souillés pour les mêmes raisons.

Dans un contexte scalaire, vous obtenez le nom sauf lorsque la
fonction

fait une recherche par nom auquel cas vous récupérerez autre chose.
(Si

une entrée n'existe pas vous récupérerez la valeur undef.) Par exemple
:


$uid = getpwnam($name);
$name = getpwuid($num);
$name = getpwent();
$gid = getgrnam($name);
$name = getgrgid($num;
$name = getgrent();
#etc.


--
Paul Gaborit - <http://www.enstimac.fr/~gaborit/>
Perl en français - <http://www.enstimac.fr/Perl/>



Avatar
Paul Gaborit
À (at) Fri, 17 Sep 2004 08:36:48 +0200,
"Pierre-Yves" <pyu-at-belbone.be> écrivait (wrote):
C'est exactement ce qu'il me fallait... je ne connaissais pas ces fonctions
(je connais mieux unix que perl).


Ces fonctions sont l'exacte reproduction de leurs homologues Unixiennes (de la
libc).

Maintenant mon script fonctionne parfaitement :-)


Enchanté que cela vous serve.

PS: inutile de recopier l'intégralité d'un message pour y répondre. Ne gardez
que les parties nécessaires à la compréhension de votre réponse. De plus, il
vaut mieux répondre après la réponse qu'avant : l'ordre de lecture reste alors
logique. Merci.

--
Paul Gaborit - <http://www.enstimac.fr/~gaborit/>
Perl en français - <http://www.enstimac.fr/Perl/>