Potrei passare da/etc/passwd ma sembra oneroso. 'finger' non è installato e vorrei evitare questa dipendenza. Questo è per un programma quindi sarebbe bello se ci fosse un comando che ti permetta di accedere alle informazioni dell'utente.Qual è il modo più semplice per ottenere il nome completo di un utente su un sistema Linux/POSIX?
risposta
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.
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.
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;
}
Prova questo:
getent passwd eutl420 | awk -F':' '{gsub(",", "",$5); print $5}'
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.
Il buon vecchio dito può anche aiutare :-)
finger $USER |head -n1 |cut -d : -f3
OP il dito menzionato non è stato installato almeno un anno prima ha postato questa risposta;) –
Le prime due risposte possono essere combinati in una sola riga:
getent passwd <username> | cut -d ':' -f 5 | cut -d ',' -f 1
Combinazione di altre risposte, testato su Debian minimale/Installazioni di Ubuntu:
getent passwd `whoami` | cut -d ':' -f 5 | cut -d ',' -f 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
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
uvetta isterica? – dat
@dat, vedere http://catb.org/jargon/html/H/hysterical-reasons.html – bignose
Non ha funzionato per me. Ma questo ha fatto: 'get passwd | grep "$ USER" | cut -d ":" -f5 | cut -d "," -f1' –