database 在 Linux/POSIX 系统上获取用户全名的最简单方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/833227/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 07:17:57  来源:igfitidea点击:

What's the easiest way to get a user's full name on a Linux/POSIX system?

databaselinuxshellposixuser-accounts

提问by Josh Gibson

I could grep through /etc/passwd but that seems onerous. 'finger' isn't installed and I'd like to avoid that dependency. This is for a program so it would be nice if there was some command that let you just access user info.

我可以通过 /etc/passwd grep 但这似乎很麻烦。'finger' 没有安装,我想避免这种依赖。这是一个程序,所以如果有一些命令可以让您访问用户信息,那就太好了。

回答by bignose

You don't specify a programming language, so I'll assume you want to use the shell; here's an answer for Posix shells.

您没有指定编程语言,所以我假设您想使用 shell;这是Posix shells 的答案

Two steps to this: get the appropriate record, then get the field you want from that record.

两个步骤:获取适当的记录,然后从该记录中获取您想要的字段。

First, getting the account record is done by querying the passwdtable:

首先,通过查询passwd表来获取帐户记录:

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

For hysterical raisins, the full name of the user is recorded in a field called the “GECOS” field; to complicate matters, this field often has its own structure with the full name as just one of several optional sub-fields. So anything that wants to get the full name from the account record needs to parse both these levels.

对于歇斯底里的葡萄干,用户的全名记录在名为“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

Your programming language probably has a library functionto do this in fewer steps. In C, you'd use the ‘getpwnam' function and then parse the GECOS field.

您的编程语言可能有一个库函数,可以通过更少的步骤完成此操作。在 C 中,您将使用 'getpwnam' 函数,然后解析 GECOS 字段。

回答by David Schmitt

On a modern glibc system, use this command:

在现代 glibc 系统上,使用以下命令:

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

That'll get you the passwdentry of the specified user, independent of the underlying NSS module.

这将使您获得passwd指定用户的条目,独立于底层 NSS 模块。

Read the manpage of getent.

阅读的手册页getent



If you're already programming, you can use the getpwnam()C-Function:

如果您已经在编程,则可以使用getpwnam()C-Function:

struct passwd *getpwnam(const char *name);

The passwdstruct has a pw_gecosmember which should contain the full name of the user.

passwd结构有一个pw_gecos成员,该成员应包含用户的全名。

Read the manpage of getpwnam().

阅读的手册页getpwnam()



Be aware that many systems use this field for more than the full name of the user. The most common convention is to use a comma (,) as separator within the field and place the users real name first.

请注意,许多系统使用此字段不仅仅是用户的全名。最常见的约定是,在字段中使用逗号 ( ) 作为分隔符,并将用户的真实姓名放在首位。

回答by David Schmitt

Just in case you want to do this from C, try something like this:

以防万一您想从 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 '
getent passwd `whoami` | cut -d ':' -f 5 | cut -d ',' -f 1
'). 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] = '
getent passwd eutl420 | awk -F':' '{gsub(",", "",); print }'
'; 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; }

回答by Tombart

Combination of other answers, tested on minimal Debian/Ubuntu installations:

其他答案的组合,在最小的 Debian/Ubuntu 安装上进行了测试:

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

回答by Rob L

Try this:

尝试这个:

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

回答by AstroFloyd

The top two answers can be combined in one line:

前两个答案可以合并为一行:

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

回答by Sam Watkins

My code works in bash and ksh, but not dash or old Bourne shell. It reads the other fields too, in case you might want them.

我的代码适用于 bash 和 ksh,但不适用于 dash 或旧的 Bourne shell。它也会读取其他字段,以防您需要它们。

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

You could also scan the whole /etc/passwd file. This works in plain Bourne shell, in 1 process, but not so much with LDAP or what.

您还可以扫描整个 /etc/passwd 文件。这在普通的 Bourne shell 中工作,在 1 个进程中,但在 LDAP 或其他方面则不然。

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

On the other hand, using tools is good. And C is good too.

另一方面,使用工具是好的。而且C也不错。

回答by TheTechCode

The way that I figured it on Linux to get the full name into a variable was:

我认为在 Linux 上将全名放入变量的方法是:

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

Then just simple use the variable, ex: $ echo $uname

然后只需简单地使用变量,例如: $ echo $uname

回答by abufct

Take 1:

采取1:

$ 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

However, passwd database supports special character '&' in the gecos, which should replaced with capitalized value of user name:

但是,passwd 数据库支持 gecos 中的特殊字符“&”,应将其替换为用户名的大写值:

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

Most of answers here (except for finger solution) do not respect &. If you want to support this case, then you'll need a more complicated script.

这里的大多数答案(手指解决方案除外)都不尊重 &。如果你想支持这种情况,那么你需要一个更复杂的脚本。

Take 2:

采取2:

##代码##

回答by H.-Dirk Schmitt

The good old fingermay also help :-)

好的老手指也可能有帮助:-)

##代码##