Quel est le moyen le plus simple d'obtenir le nom complet d'un utilisateur sur un système Linux / POSIX?
-
08-07-2019 - |
Question
Je pourrais passer par / etc / passwd, mais cela semble difficile. 'finger' n'est pas installé et j'aimerais éviter cette dépendance. Ceci est pour un programme donc ce serait bien s'il y avait une commande qui vous permettait juste d'accéder aux informations de l'utilisateur.
La solution
Vous ne spécifiez pas de langage de programmation, je suppose donc que vous souhaitez utiliser le shell; voici une réponse pour les coques Posix .
Deux étapes à cela: obtenir l'enregistrement approprié, puis obtenir le champ souhaité à partir de cet enregistrement.
Tout d'abord, l'enregistrement du compte est obtenu en interrogeant la table passwd
:
$ user_name=foo
$ user_record="$(getent passwd $user_name)"
$ echo "$user_record"
foo:x:1023:1025:Fred Nurk,,,:/home/foo:/bin/bash
Pour les raisins secs hystériques, le nom complet de l'utilisateur est enregistré dans un champ appelé & GECOS & # 8221; champ ; pour compliquer les choses, ce champ possède souvent sa propre structure avec le nom complet en tant que simple sous-champ facultatif . Donc, tout ce qui veut obtenir le nom complet de l’enregistrement de compte doit analyser ces deux niveaux.
$ user_record="$(getent passwd $user_name)"
$ user_gecos_field="$(echo "$user_record" | cut -d ':' -f 5)"
$ user_full_name="$(echo "$user_gecos_field" | cut -d ',' -f 1)"
$ echo "$user_full_name"
Fred Nurk
Votre langage de programmation dispose probablement d'une fonction de bibliothèque permettant d'effectuer cette opération en moins d'étapes. En C, vous utiliseriez le fichier & # 8216; getpwnam & # 8217; fonction et ensuite analyser le champ GECOS.
Autres conseils
Sur un système glibc moderne, utilisez cette commande:
getent passwd "username" | cut -d ':' -f 5
Cela vous donnera l'entrée passwd
de l'utilisateur spécifié, indépendamment du module NSS sous-jacent.
Lisez la page de manuel de getent
. .
Si vous programmez déjà, vous pouvez utiliser la getpwnam ()
:
struct passwd *getpwnam(const char *name);
La structure passwd
a un membre pw_gecos
qui doit contenir le nom complet de l'utilisateur.
Lisez la page de manuel de getpwnam ()
.
Sachez que de nombreux systèmes utilisent ce champ pour plus que le nom complet de l'utilisateur. La convention la plus courante consiste à utiliser une virgule (,
) comme séparateur dans le champ et à placer en premier le nom réel de l'utilisateur.
Juste au cas où vous voudriez faire cela depuis C, essayez quelque chose comme ça:
#include <sys/types.h>
#include <pwd.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
/* Get full name of a user, given their username. Return 0 for not found,
-1 for error, or 1 for success. Copy name to `fullname`, but only up
to max-1 chars (max includes trailing '\0'). Note that if the GECOS
field contains commas, only up to to (but not including) the first comma
is copied, since the commas are a convention to add more than just the
name into the field, e.g., room number, phone number, etc. */
static int getfullname(const char *username, char *fullname, size_t max)
{
struct passwd *p;
size_t n;
errno = 0;
p = getpwnam(username);
if (p == NULL && errno == 0)
return 0;
if (p == NULL)
return -1;
if (max == 0)
return 1;
n = strcspn(p->pw_gecos, ",");
if (n > max - 1)
n = max - 1;
memcpy(fullname, p->pw_gecos, n);
fullname[n] = '\0';
return 1;
}
int main(int argc, char **argv)
{
int i;
int ret;
char fullname[1024];
for (i = 1; i < argc; ++i) {
ret = getfullname(argv[i], fullname, sizeof fullname);
if (ret == -1)
printf("ERROR: %s: %s\n", argv[i], strerror(errno));
else if (ret == 0)
printf("UNKONWN: %s\n", argv[i]);
else
printf("%s: %s\n", argv[i], fullname);
}
return 0;
}
Combinaison d'autres réponses, testée sur des installations minimales de Debian / Ubuntu:
getent passwd `whoami` | cut -d ':' -f 5 | cut -d ',' -f 1
Essayez ceci:
getent passwd eutl420 | awk -F':' '{gsub(",", "",$5); print $5}'
Les deux premières réponses peuvent être combinées en une seule ligne:
getent passwd <username> | cut -d ':' -f 5 | cut -d ',' -f 1
Mon code fonctionne en bash et en ksh, mais pas avec dash ou vieux shell Bourne. Il lit également les autres champs, au cas où vous les voudriez.
IFS=: read user x uid gid gecos hm sh < <( getent passwd $USER )
name=${gecos%%,*}
echo "$name"
Vous pouvez également analyser l’ensemble du fichier / etc / passwd. Cela fonctionne en clair Bourne Shell, en 1 processus, mais pas autant avec LDAP ou quoi.
while IFS=: read user x uid gid gecos hm sh; do
name=${gecos%%,*}
[ $uid -ge 1000 -a $uid -lt 60000 ] && echo "$name"
done < /etc/passwd
D'autre part, utiliser des outils est bon. Et C est bon aussi.
La façon dont je l'ai trouvé sous Linux pour obtenir le nom complet dans une variable était:
u_id=`id -u`
uname=`awk -F: -vid=$u_id '{if ($3 == id) print $5}' /etc/passwd`
Ensuite, utilisez simplement la variable, par exemple: $ echo $ uname
Prenez 1:
$ user_name=sshd
$ awk -F: "\$1 == \"$user_name\" { print \$5 }" /etc/passwd
Secure Shell Daemon
Cependant, la base de données passwd prend en charge le caractère spécial '& amp;' dans les gecos, qui doivent être remplacés par la valeur en majuscule du nom d'utilisateur:
$ user_name=operator
$ awk -F: "\$1 == \"$user_name\" { print \$5 }" /etc/passwd
System &
La plupart des réponses ici (sauf pour la solution pour les doigts) ne respectent pas & amp; Si vous souhaitez prendre en charge ce cas, vous aurez besoin d’un script plus complexe.
Prenez 2:
$ user_name=operator
$ awk -F: "\$1 == \"$user_name\" { u=\$1; sub(/./, toupper(substr(u,1,1)), u);
gsub(/&/, u, \$5); print \$5 }" /etc/passwd
System Operator
Le bon vieux doigt peut aussi aider: -)
finger $USER |head -n1 |cut -d : -f3