2009-05-07 9 views

risposta

40

Non si specifica un linguaggio di programmazione, quindi presumo che si voglia utilizzare la shell; Ecco una risposta per le shell Posix.

Due passaggi: ottenere il record appropriato, quindi ottenere il campo desiderato da quel record.

In primo luogo, ottenendo il record di conto è fatto da interrogando la passwd tavolo:

$ user_name=foo 
$ user_record="$(getent passwd $user_name)" 
$ echo "$user_record" 
foo:x:1023:1025:Fred Nurk,,,:/home/foo:/bin/bash 

Per uvetta isteriche, il nome completo dell'utente viene registrato in un campo chiamato “GECOS” field; per complicare le cose, questo campo ha spesso una propria struttura con il nome completo come uno dei diversi campi secondari opzionali. Quindi tutto ciò che vuole ottenere il nome completo dal record dell'account deve analizzare entrambi questi livelli.

$ 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 

tuo linguaggio di programmazione ha probabilmente una funzione di libreria di farlo in meno passaggi. In C, dovresti usare la funzione 'getpwnam' e quindi analizzare il campo GECOS.

+3

uvetta isterica? – dat

+1

@dat, vedere http://catb.org/jargon/html/H/hysterical-reasons.html – bignose

+2

Non ha funzionato per me. Ma questo ha fatto: 'get passwd | grep "$ USER" | cut -d ":" -f5 | cut -d "," -f1' –

20

Su un sistema glibc moderno, utilizzare questo comando:

getent passwd "username" | cut -d ':' -f 5 

che otterrà la passwd ingresso dell'utente specificato, indipendentemente dal modulo di NSS sottostante.

Leggi il manpage of getent.


Se sei già la programmazione, è possibile utilizzare il getpwnam() C-Function:

struct passwd *getpwnam(const char *name); 

Il passwd struttura ha un membro pw_gecos che dovrebbe contenere il nome completo dell'utente.

Leggi manpage of getpwnam().


Si noti che molti sistemi utilizzano questo campo per più del nome completo dell'utente. La convenzione più comune consiste nell'utilizzare una virgola (,) come separatore all'interno del campo e posizionare prima il nome reale dell'utente.

8

Solo nel caso in cui si vuole fare questo da C, provare qualcosa di simile:

#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; 
} 
6

Prova questo:

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

mio codice funziona in bash e ksh, ma non precipitare o vecchio Bourne shell. Legge anche gli altri campi, nel caso tu li voglia.

IFS=: read user x uid gid gecos hm sh < <(getent passwd $USER) 
name=${gecos%%,*} 
echo "$name" 

È anche possibile eseguire la scansione dell'intero file/etc/passwd. Funziona con una semplice shell Bourne, in 1 processo, ma non così tanto con LDAP o cosa.

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'altra parte, l'utilizzo di strumenti è buono. Anche C è buono.

-2

Il buon vecchio dito può anche aiutare :-)

finger $USER |head -n1 |cut -d : -f3 
+1

OP il dito menzionato non è stato installato almeno un anno prima ha postato questa risposta;) –

5

Le prime due risposte possono essere combinati in una sola riga:

getent passwd <username> | cut -d ':' -f 5 | cut -d ',' -f 1 
7

Combinazione di altre risposte, testato su Debian minimale/Installazioni di Ubuntu:

getent passwd `whoami` | cut -d ':' -f 5 | cut -d ',' -f 1 
-1

Take 1:

$ user_name=sshd 
$ awk -F: "\$1 == \"$user_name\" { print \$5 }" /etc/passwd 
Secure Shell Daemon 

Tuttavia, database di passwd supporta carattere speciale '&' nei gecos, che dovrebbe sostituito con valore capitalizzato nome utente:

$ user_name=operator 
$ awk -F: "\$1 == \"$user_name\" { print \$5 }" /etc/passwd 
System & 

La maggior parte delle risposte qui (tranne che per soluzione dito) non lo fanno rispetto &. Se vuoi supportare questo caso, avrai bisogno di uno script più complicato.

Take 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 
0

Il modo in cui ho pensato che su Linux per ottenere il nome completo in una variabile era:

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

Poi basta semplice utilizzare la variabile, es: $ echo $uname