Script utilisateurs logués
Résolu
kamax
-
kamax -
kamax -
Bonjour,
je dois faire un script qui m'affiche tous les utilisateurs logués sur le système et afficher les processus actifs. L'en-tête, pour chaque utilisateur doit être leur nom réel et non leur loggin name (ex: belkacem berbache et non pas belkacem.berbache).
Chaque utilisateur ne doit être affichés qu'une seule fois.
Le tout sera sauvegardé dans un fichier.
En sortie, le résultat devra ressembler à ceci :
belkacem berbache
PID TTY TIME CMD
31799 pts/3 00:00:00 vim
31866 pts/3 00:00:00 vim
2495 pts/7 00:00:00 vim
8368 pts/0 00:00:00 vim
9544 pts/2 00:00:00 ps
dupont jean
PID TTY TIME CMD
31799 pts/3 00:00:00 vim
31866 pts/3 00:00:00 vim
2495 pts/7 00:00:00 vim
8368 pts/0 00:00:00 vim
9544 pts/2 00:00:00 ps
etc...
je dois faire un script qui m'affiche tous les utilisateurs logués sur le système et afficher les processus actifs. L'en-tête, pour chaque utilisateur doit être leur nom réel et non leur loggin name (ex: belkacem berbache et non pas belkacem.berbache).
Chaque utilisateur ne doit être affichés qu'une seule fois.
Le tout sera sauvegardé dans un fichier.
En sortie, le résultat devra ressembler à ceci :
belkacem berbache
PID TTY TIME CMD
31799 pts/3 00:00:00 vim
31866 pts/3 00:00:00 vim
2495 pts/7 00:00:00 vim
8368 pts/0 00:00:00 vim
9544 pts/2 00:00:00 ps
dupont jean
PID TTY TIME CMD
31799 pts/3 00:00:00 vim
31866 pts/3 00:00:00 vim
2495 pts/7 00:00:00 vim
8368 pts/0 00:00:00 vim
9544 pts/2 00:00:00 ps
etc...
A voir également:
- Script utilisateurs logués
- Script vidéo youtube - Guide
- Ghost script - Télécharger - Polices de caractères
- Mas script - Accueil - Windows
- Script cmd - Guide
- Gestion des utilisateurs windows 10 - Guide
12 réponses
Salut,
ce cas je pense aussi qu'il a été traité, mais je ne me rappelle toujours pas le lien :-(
allez jipicy, donne un coup de main ;-))
ce cas je pense aussi qu'il a été traité, mais je ne me rappelle toujours pas le lien :-(
allez jipicy, donne un coup de main ;-))
Non en fait c'est pour moi, je suis diplômé en informatique depuis 2001. Depuis je ne suis pas parvenu à trouver un poste. Aujourd'hui je souhaiterai faire une remise à niveau, ou plus précisément me spécialiser sur Unix/Linux.Voilà.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Peux-tu m'aider à argumenter ton script pour mieux le comprendre stp?
$(ps auc | grep -v USER |cut -d " " -f 1 | sort | uniq) :
=>tu utilises ps auc et non pas ps car il y a le champ USER
=>grep -v USER prend toutes les lignes où ne figure pas USER
=>ensuite tu ne prends que le premier champ(cut va extraire le premier, : fixant le séparateur de champ), tu le tries (sort) et tu supprimes les doublons (uniq)
Je ne comprend pas à quoi te sert le grep -v ???
Donc tu fais une boucle sur le name et tu récupères dans etc/passwd le nom et prenom qui sont au champs 5 grâce à grep "$name" /etc/passwd | cut -d: -f5
set $(ps | head -1) => te permet d'avoir ton en-tête (PID TTY TIME CMD)
printf "%s$1%s\t$2%s\t$3%s\t$4\n" => pourquoi utiliser printf et non pas echo ici?? comment sait-on que $1correspond à PID, $2 à TTY ...????
for name in $(ps auc | grep -v USER |cut -d " " -f 1 | sort | uniq)
do
grep "$name" /etc/passwd | cut -d: -f5
set $(ps | head -1)
printf "%s$1%s\t$2%s\t$3%s\t$4\n"
------------------------------------
(
OLDIFS=$IFS => ça correspond à quoi?
IFS=$'\n'
for line in $(ps auc | grep "$name")
do
IFS=$OLDIFS
set $(echo $line)
printf "%s$2\t%s$7\t%s${10}\t%s${11}\n"
done
)
---------------------------------
echo
done
Voilà, avant d'approfondir davantage, peux-tu m'expliquer ces points stp ?
$(ps auc | grep -v USER |cut -d " " -f 1 | sort | uniq) :
=>tu utilises ps auc et non pas ps car il y a le champ USER
=>grep -v USER prend toutes les lignes où ne figure pas USER
=>ensuite tu ne prends que le premier champ(cut va extraire le premier, : fixant le séparateur de champ), tu le tries (sort) et tu supprimes les doublons (uniq)
Je ne comprend pas à quoi te sert le grep -v ???
Donc tu fais une boucle sur le name et tu récupères dans etc/passwd le nom et prenom qui sont au champs 5 grâce à grep "$name" /etc/passwd | cut -d: -f5
set $(ps | head -1) => te permet d'avoir ton en-tête (PID TTY TIME CMD)
printf "%s$1%s\t$2%s\t$3%s\t$4\n" => pourquoi utiliser printf et non pas echo ici?? comment sait-on que $1correspond à PID, $2 à TTY ...????
for name in $(ps auc | grep -v USER |cut -d " " -f 1 | sort | uniq)
do
grep "$name" /etc/passwd | cut -d: -f5
set $(ps | head -1)
printf "%s$1%s\t$2%s\t$3%s\t$4\n"
------------------------------------
(
OLDIFS=$IFS => ça correspond à quoi?
IFS=$'\n'
for line in $(ps auc | grep "$name")
do
IFS=$OLDIFS
set $(echo $line)
printf "%s$2\t%s$7\t%s${10}\t%s${11}\n"
done
)
---------------------------------
echo
done
Voilà, avant d'approfondir davantage, peux-tu m'expliquer ces points stp ?
Je ne comprend pas à quoi te sert le grep -v ???
A empêcher l'affichage de la 1ère ligne :
Donc tu fais une boucle sur le name et tu récupères dans etc/passwd le nom et prenom qui sont au champs 5 grâce à grep "$name" /etc/passwd | cut -d: -f5
Yes.
set $(ps | head -1) => te permet d'avoir ton en-tête (PID TTY TIME CMD)
Oui et d'initialiser les paramètres $1 $2 $3 $4 avec leur valeur respective pour leur emploi futur avec mise en page.
printf "%s$1%s\t$2%s\t$3%s\t$4\n" => pourquoi utiliser printf et non pas echo ici??
Pour mieux gérer la mise en page.
comment sait-on que $1correspond à PID, $2 à TTY ...????
C'est le rôle de la commande "set" vu plus haut. Elle permet d'initialiser des paramètres.
OLDIFS=$IFS => ça correspond à quoi?
La variable d'environnement "$IFS" contient le séparateur de champs par défaut (espace).
Donc comme on a besoin de la modifier pour l'intérêt du script, on fait juste une sauvegarde avant.
Pour entrer plus dans le détail, comme nous allons partir sur une boucle "for" et si nous laissons la variable $IFS dans son état par défaut, au lieu de traiter une ligne entière dans la boucle qui suit, on traitera un à un chaque mot séparé par un espace. C'est pourquoi après l'avoir sauvegardée on l'initialise avec la valeur "saut de ligne" qui se traduit par IFS=$'\n'. A partir de là, la boucle traitera à chaque itération une ligne complète.
Comme un exemple est toujours plus parlant :
A empêcher l'affichage de la 1ère ligne :
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMANDça marcherait pareil avec "grep -v PID" ou "grep -v MEM".
Donc tu fais une boucle sur le name et tu récupères dans etc/passwd le nom et prenom qui sont au champs 5 grâce à grep "$name" /etc/passwd | cut -d: -f5
Yes.
set $(ps | head -1) => te permet d'avoir ton en-tête (PID TTY TIME CMD)
Oui et d'initialiser les paramètres $1 $2 $3 $4 avec leur valeur respective pour leur emploi futur avec mise en page.
printf "%s$1%s\t$2%s\t$3%s\t$4\n" => pourquoi utiliser printf et non pas echo ici??
Pour mieux gérer la mise en page.
comment sait-on que $1correspond à PID, $2 à TTY ...????
C'est le rôle de la commande "set" vu plus haut. Elle permet d'initialiser des paramètres.
OLDIFS=$IFS => ça correspond à quoi?
La variable d'environnement "$IFS" contient le séparateur de champs par défaut (espace).
Donc comme on a besoin de la modifier pour l'intérêt du script, on fait juste une sauvegarde avant.
Pour entrer plus dans le détail, comme nous allons partir sur une boucle "for" et si nous laissons la variable $IFS dans son état par défaut, au lieu de traiter une ligne entière dans la boucle qui suit, on traitera un à un chaque mot séparé par un espace. C'est pourquoi après l'avoir sauvegardée on l'initialise avec la valeur "saut de ligne" qui se traduit par IFS=$'\n'. A partir de là, la boucle traitera à chaque itération une ligne complète.
Comme un exemple est toujours plus parlant :
[tmpfs]$ echo -e "1 2 3\n4 5 6\n7 8 9" > kamax [tmpfs]$ cat kamax 1 2 3 4 5 6 7 8 9 [tmpfs]$ for line in $(cat kamax); do echo "$line"; done 1 2 3 4 5 6 7 8 9 [tmpfs]$ OLD_IFS=$IFS; IFS=$'\n'; for line in $(cat kamax); do echo "$line"; done; IFS=$OLD_IFS 1 2 3 4 5 6 7 8 9 [tmpfs]$;-))
Oula ! Doit manquer des trucs parce que ça merdoie grave ;-((
ben, non, regarde le résultat
ben, non, regarde le résultat
lami20j@deb:~$ perl -e'for(qx/ps --no-headers -eouser,pid,tty,time,cmd/){($k,$v)=split/\s+/,$_,2;push@{$h{$k}},$v}for(sort keys%h){print "$_\nPID\tTTY\tTIME\tCMD\n@{$h{$_}}\n\n"}'> aaaaa
lami20j@deb:~$ head -30 aaaaa
103
PID TTY TIME CMD
2772 ? 00:00:00 /usr/bin/dbus-daemon --system
105
PID TTY TIME CMD
2780 ? 00:00:03 /usr/sbin/hald
2787 ? 00:00:00 hald-addon-acpi: listening on acpid socket /var/run/acpid.socket
2790 ? 00:00:00 hald-addon-keyboard: listening on /dev/input/event0
avahi
PID TTY TIME CMD
2822 ? 00:00:00 avahi-daemon: running [debian.local]
2823 ? 00:00:00 avahi-daemon: chroot helper
daemon
PID TTY TIME CMD
2275 ? 00:00:00 /sbin/portmap
3020 ? 00:00:00 /usr/sbin/atd
lami20j
PID TTY TIME CMD
3217 ? 00:00:00 x-session-manager
3264 ? 00:00:00 /usr/bin/ssh-agent /usr/bin/dbus-launch --exit-with-session x-session-manager
3267 ? 00:00:00 /usr/bin/dbus-launch --exit-with-session x-session-manager
3268 ? 00:00:00 /usr/bin/dbus-daemon --fork --print-pid 4 --print-address 6 --session
lami20j@deb:~$
#! /bin/bash
for name in $(ps auc | sed '1d' | awk '{ print $1 }'| sort | uniq)
do
grep "$name" /etc/passwd | cut -d: -f5
ps | head -1 | awk '{ printf "%s \t%s \t%s \t%s\n",$1,$2,$3,$4 }'
ps auc | grep "$name" | awk '{ printf "%s \t%s \t%s \t%s\n",$2,$7,$10,$11 }'
echo
done
[tmpfs]$ ./foo.sh
Jean-Philippe
PID TTY TIME CMD
4002 pts/1 0:00 bash
5027 pts/2 0:00 bash
5244 pts/2 0:00 man
5247 pts/2 0:00 sh
5248 pts/2 0:00 sh
5253 pts/2 0:00 less
7357 pts/1 0:00 foo.sh
7369 pts/1 0:00 ps
root
PID TTY TIME CMD
3096 tty7 63:48 X
3724 tty1 0:00 mingetty
3725 tty2 0:00 mingetty
3726 tty3 0:00 mingetty
3727 tty4 0:00 mingetty
3728 tty5 0:00 mingetty
3729 tty6 0:00 mingetty
[tmpfs]$
Bonjour,
la seconde boucle for me pose problème !!
Une fois l'en-tête récupérée pour chaque user,
for line in $(ps auc | grep "$name") => tu fais une boucle pour chaque user afin d'afficher ses processus actifs.
do
IFS=$OLDIFS => tu restaures la valeur par défaut de IFS afin d'avoir ton résultat sur une ligne
set $(echo $line) => la commande set sert à positionner des paramètres, comment fonctionne-t-elle dans ce cas présent?
printf "%s$2\t%s$7\t%s${10}\t%s${11}\n" => je ne comprends pas les paramètres ?? Aussi à quoi sert les % ?peux-tu m'expliquer les
done => différences d'affichage entre printf et echo -e ??
Merci.
la seconde boucle for me pose problème !!
Une fois l'en-tête récupérée pour chaque user,
for line in $(ps auc | grep "$name") => tu fais une boucle pour chaque user afin d'afficher ses processus actifs.
do
IFS=$OLDIFS => tu restaures la valeur par défaut de IFS afin d'avoir ton résultat sur une ligne
set $(echo $line) => la commande set sert à positionner des paramètres, comment fonctionne-t-elle dans ce cas présent?
printf "%s$2\t%s$7\t%s${10}\t%s${11}\n" => je ne comprends pas les paramètres ?? Aussi à quoi sert les % ?peux-tu m'expliquer les
done => différences d'affichage entre printf et echo -e ??
Merci.
set $(echo $line) => la commande set sert à positionner des paramètres, comment fonctionne-t-elle dans ce cas présent?
Elle se présente sous la forme suivante :
De ce fait l'appel à la commande "set" positionne chaque champ séparé par un espace dans un paramètre positionnel, représenté par $1, $2, $3,...$9, ${10}, ${11}, etc...
Donc "set $(echo $line)" revient en fait à faire :
$1 = jp
$2 = 5327
$3 = 0.0
etc...
printf "%s$2\t%s$7\t%s${10}\t%s${11}\n" => je ne comprends pas les paramètres ?
Voir au-dessus
Aussi à quoi sert les % ?
Ça indique le début d'une directive, le "s" désignant une chaine de caractères ("d" pour un entier décimal et "f" pour un nombre réel).
Dans l'expression "%s$2\t", on demande à ce que la sortie soit formatée de façon à ce que la chaine de caractère (%s) contenu dans le 2nd paramètre "$2" soit affichée suivie d'une tabulation "\t".
man "printf" pour plus de détails
peux-tu m'expliquer les done => différences d'affichage entre printf et echo -e ?
En fait l'expression aurait du s'écrire de cette façon (il est vrai qu'avec "echo -e" tu aurais eu le même résultat) :
Elle se présente sous la forme suivante :
echo $line jp 5327 0.0 0.2 2124 756 pts/1 S+ 12:22 0:00 grep
De ce fait l'appel à la commande "set" positionne chaque champ séparé par un espace dans un paramètre positionnel, représenté par $1, $2, $3,...$9, ${10}, ${11}, etc...
Donc "set $(echo $line)" revient en fait à faire :
set jp 5327 0.0 0.2 2124 756 pts/1 S+ 12:22 0:00 grepet à partir de là :
$1 = jp
$2 = 5327
$3 = 0.0
etc...
printf "%s$2\t%s$7\t%s${10}\t%s${11}\n" => je ne comprends pas les paramètres ?
Voir au-dessus
Aussi à quoi sert les % ?
Ça indique le début d'une directive, le "s" désignant une chaine de caractères ("d" pour un entier décimal et "f" pour un nombre réel).
Dans l'expression "%s$2\t", on demande à ce que la sortie soit formatée de façon à ce que la chaine de caractère (%s) contenu dans le 2nd paramètre "$2" soit affichée suivie d'une tabulation "\t".
man "printf" pour plus de détails
peux-tu m'expliquer les done => différences d'affichage entre printf et echo -e ?
En fait l'expression aurait du s'écrire de cette façon (il est vrai qu'avec "echo -e" tu aurais eu le même résultat) :
printf "%-5d%-6s%-5s%s\n" $2 $7 ${10} ${11}ou :echo -e "$2\t$7\t${10}\t${11};-))
Moi non plus je le rappelle pas le lien, mais notre ami "google", oui ;-))
Ok, ok, mais je suis au boulot et je n'ai pas le temps de chercher ;-))
perl -e'for(qx/ps --no-headers -eouser,pid,tty,time,cmd/){($k,$v)=split/\s+/,$_,2;push@{$h{$k}},$v}for(sort keys%h){print "$_\nPID\tTTY\tTIME\tCMD\n@{$h{$_}}\n\n"}'