Какой самый простой способ получить полное имя пользователя в системе Linux / POSIX?
-
08-07-2019 - |
Вопрос
Я мог бы выполнить grep через /etc/passwd, но это кажется обременительным.'finger' не установлен, и я бы хотел избежать этой зависимости.Это для программы, поэтому было бы неплохо, если бы существовала какая-нибудь команда, которая позволяла бы вам просто получить доступ к информации о пользователе.
Решение
Вы не указываете язык программирования, поэтому я предполагаю, что вы хотите использовать оболочку;вот ответ для оболочек Posix.
Два шага к этому:получите соответствующую запись, затем получите нужное поле из этой записи.
Во-первых, получение записи учетной записи осуществляется с помощью запрашивая passwd
таблица:
$ user_name=foo
$ user_record="$(getent passwd $user_name)"
$ echo "$user_record"
foo:x:1023:1025:Fred Nurk,,,:/home/foo:/bin/bash
Для hysterical raisins полное имя пользователя записывается в поле под названием Поле “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.
Другие советы
В современной системе glibc используйте эту команду:
getent passwd "username" | cut -d ':' -f 5
Это даст вам запись passwd
указанного пользователя, независимую от базового модуля NSS.
Прочитайте страницу getent
. . р>
<Ч>
Если вы уже программируете, вы можете использовать функцию C getpwnam ()
:
struct passwd *getpwnam(const char *name);
Структура passwd
содержит элемент pw_gecos
, который должен содержать полное имя пользователя.
Прочтите страницу getpwnam ()
. р>
<Ч>
Имейте в виду, что многие системы используют это поле не только для полного имени пользователя. Наиболее распространенное соглашение - использовать запятую (,
) в качестве разделителя в поле и ставить имя пользователя первым.
На всякий случай, если вы хотите сделать это из 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;
}
Сочетание других ответов, протестированных на минимальных установках Debian / Ubuntu:
getent passwd `whoami` | cut -d ':' -f 5 | cut -d ',' -f 1
Попробуйте это:
getent passwd eutl420 | awk -F':' '{gsub(",", "",$5); print $5}'
Два верхних ответа можно объединить в одну строку:
getent passwd <username> | cut -d ':' -f 5 | cut -d ',' -f 1
Мой код работает в 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
С другой стороны, использование инструментов - это хорошо. И С тоже хорошо.
В Linux я понял, как получить полное имя в переменной:
u_id=`id -u`
uname=`awk -F: -vid=$u_id '{if ($3 == id) print $5}' /etc/passwd`
Тогда просто используйте переменную, например: $ echo $ uname
Взять 1:
$ user_name=sshd
$ awk -F: "\$1 == \"$user_name\" { print \$5 }" /etc/passwd
Secure Shell Daemon
Однако база данных passwd поддерживает специальный символ '& amp;' в gecos, который следует заменить на заглавную стоимость имени пользователя:
$ user_name=operator
$ awk -F: "\$1 == \"$user_name\" { print \$5 }" /etc/passwd
System &
Большинство ответов здесь (за исключением решения пальцем) не относятся к & amp ;. Если вы хотите поддержать этот случай, вам понадобится более сложный скрипт.
Взять 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
Старый добрый палец также может помочь: -)
finger $USER |head -n1 |cut -d : -f3