web-dev-qa-db-fra.com

Quel est le moyen le plus simple d'obtenir le nom complet d'un utilisateur sur un système Linux/POSIX?

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.

33
Josh Gibson

Vous ne spécifiez pas de langage de programmation, je suppose donc que vous souhaitez utiliser le shell; voici une réponse pour les obus Posix.

Deux étapes pour cela: obtenir l'enregistrement approprié, puis obtenir le champ souhaité à partir de cet enregistrement.

Tout d’abord, l’enregistrement du compte se fait par 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é le champ "GECOS"; pour compliquer les choses, ce champ a 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 le langage de programmation a probablement une fonction de bibliothèque pour le faire en moins d'étapes. En C, vous utiliseriez la fonction ‘getpwnam’ et ensuite analyser le champ GECOS.

42
bignose

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 fonction getpwnam() C:

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 le nom réel de l'utilisateur en premier.

24
David Schmitt

Juste au cas où vous voudriez faire ça 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;
}
8
user25148

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
7
Tombart

Essaye ça:

getent passwd eutl420 | awk -F':' '{gsub(",", "",$5); print $5}'
6
Rob L

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
5
AstroFloyd

Mon code fonctionne en bash et en ksh, mais pas dash ou old Bourne Shell. Il lit également les autres champs, au cas où vous en 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 dans 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

Par contre, utiliser des outils est bon. Et c est bon aussi.

2
Sam Watkins

La façon dont j'ai pensé que sous Linux était d'obtenir le nom complet dans une variable était la suivante:

u_id=`id -u`
uname=`awk -F: -vid=$u_id '{if ($3 == id) print $5}' /etc/passwd`

Ensuite, utilisez simplement la variable, ex: $ echo $uname

0
TheTechCode