Какой самый простой способ получить полное имя пользователя в системе Linux / POSIX? - PullRequest
34 голосов
/ 07 мая 2009

Я мог бы пройти через / etc / passwd, но это кажется обременительным. 'finger' не установлен, и я бы хотел избежать этой зависимости. Это для программы, поэтому было бы неплохо, если бы была какая-то команда, которая позволяла бы вам просто получить доступ к пользовательской информации.

Ответы [ 10 ]

44 голосов
/ 07 мая 2009

Вы не указываете язык программирования, поэтому я предполагаю, что вы хотите использовать оболочку; вот ответ для снарядов Posix .

Два шага к этому: получить соответствующую запись, затем получить нужное поле из этой записи.

Во-первых, получение учетной записи выполняется путем запроса таблицы passwd :

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

Для истерических изюмов ​​полное имя пользователя записывается в поле, называемом «GECOS» ; чтобы усложнить ситуацию, это поле часто имеет свою собственную структуру с полным именем как одно из нескольких необязательных подполей . Поэтому все, что хочет получить полное имя из записи учетной записи, должно анализировать оба этих уровня.

$ 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

Ваш язык программирования, вероятно, имеет библиотечную функцию , которая делает это за меньшее количество шагов. В C вы будете использовать функцию getpwnam, а затем проанализировать поле GECOS.

24 голосов
/ 07 мая 2009

В современной системе glibc используйте эту команду:

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

Это даст вам запись passwd указанного пользователя, независимо от базового модуля NSS.

Прочитайте справочную страницу getent.


Если вы уже программируете, вы можете использовать getpwnam() C-функцию:

struct passwd *getpwnam(const char *name);

Структура passwd имеет член pw_gecos, который должен содержать полное имя пользователя.

Прочитайте справочную страницу getpwnam().


Имейте в виду, что многие системы используют это поле не только для полного имени пользователя. Наиболее распространенное соглашение - использовать запятую (,) в качестве разделителя в поле и ставить имя пользователя первым.

8 голосов
/ 07 мая 2009

На всякий случай, если вы хотите сделать это из C, попробуйте что-то вроде этого:

#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;
}
7 голосов
/ 18 сентября 2013

Сочетание других ответов, протестированных на минимальных установках Debian / Ubuntu:

getent passwd `whoami` | cut -d ':' -f 5 | cut -d ',' -f 1
6 голосов
/ 07 июля 2011

Попробуйте это:

getent passwd eutl420 | awk -F':' '{gsub(",", "",$5); print $5}'
5 голосов
/ 02 августа 2013

Два верхних ответа можно объединить в одну строку:

getent passwd <username> | cut -d ':' -f 5 | cut -d ',' -f 1
2 голосов
/ 15 августа 2012

Мой код работает в bash и ksh, но не в dash или старой оболочке Bourne. Он также читает другие поля, на случай, если вы захотите их.

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

Вы также можете сканировать весь файл / etc / passwd. Это работает в простой оболочке Bourne, в одном процессе, но не так сильно с LDAP или чем-то.

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

С другой стороны, использование инструментов - это хорошо. И С тоже хорошо.

0 голосов
/ 31 июля 2017

В Linux я понял, как получить полное имя в переменной:

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

Тогда просто используйте переменную, например: $ echo $uname

0 голосов
/ 10 ноября 2013

дубль 1:

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

Однако база данных passwd поддерживает специальный символ '&' в gecos, который следует заменить на заглавное значение имени пользователя:

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

Большинство ответов здесь (за исключением решения пальцем) не относятся к &. Если вы хотите поддержать это дело, вам понадобится более сложный скрипт.

Взять 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 голосов
/ 13 сентября 2012

Старый добрый палец также может помочь: -)

finger $USER |head -n1 |cut -d : -f3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...