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.
10 Answers
You don't specify a programming language, so I'll assume you want to use the shell; here's an answer for 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 passwd
table:
$ 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.
$ 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 function to do this in fewer steps. In C, you'd use the ‘getpwnam’ function and then parse the GECOS field.

- 30,281
- 14
- 77
- 110
-
24hysterical raisins? – dat Apr 10 '16 at 05:18
-
2Didn't work for me. But this did: `getent passwd | grep "$USER" | cut -d":" -f5 | cut -d"," -f1` – Dean Rather May 24 '16 at 00:48
-
2Use grep "^$USER:" or getent passwd $USER to not match all usernames containing the name of the current user – nvrandow Jul 22 '16 at 16:13
-
Great answer. Here's another one-liner based on your answer that's suitable to insert somewhere in eg. /etc/profile.d export FULL_USER_NAME="$(getent passwd $USER | cut -d ':' -f 5 | cut -d ',' -f 1)" – Neil Stephens Jun 20 '23 at 01:39
On a modern glibc system, use this command:
getent passwd "username" | cut -d ':' -f 5
That'll get you the passwd
entry of the specified user, independent of the underlying NSS module.
Read the manpage of getent
.
If you're already programming, you can use the getpwnam()
C-Function:
struct passwd *getpwnam(const char *name);
The passwd
struct has a pw_gecos
member which should contain the full name of the user.
Read the manpage of 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.

- 58,259
- 26
- 121
- 165
-
3So typically the command to get only the user's real name is `getent passwd $USER | cut -d ':' -f 5 | cut -d ',' -f 1` – jpyams Aug 03 '18 at 17:01
-
1With double quotes around `$USER`, in case it contains special characters, and without quotes around `:` and `,`: `getent passwd "$USER" | cut -d: -f5 | cut -d, -f1` – Alexander Feb 01 '19 at 12:33
-
does not work `getent passwd "${USER}" | cut -d: -f5` will return `,,,` on a non sudo. EDIT: I think because the created did not have name. – MaXi32 Dec 29 '22 at 09:49
Combination of other answers, tested on minimal Debian/Ubuntu installations:
getent passwd "$USER" | cut -d ':' -f 5 | cut -d ',' -f 1

- 30,520
- 16
- 123
- 136
-
There are no practical reasons to invoke a subshell for `whoami`, you can use any username directly as an argument. And if _must_ use a subshell, please don't advocate backsticks, use `$()`. But in this case `"$USER"` makes much more sene – MestreLion Apr 20 '21 at 13:23
Just in case you want to do this from C, try something like this:
#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;
}
Try this:
getent passwd eutl420 | awk -F':' '{gsub(",", "",$5); print $5}'

- 2,336
- 5
- 31
- 40

- 81
- 1
- 1
The top two answers can be combined in one line:
getent passwd <username> | cut -d ':' -f 5 | cut -d ',' -f 1

- 405
- 5
- 14
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.
IFS=: read user x uid gid gecos hm sh < <( getent passwd $USER )
name=${gecos%%,*}
echo "$name"
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.
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
On the other hand, using tools is good. And C is good too.

- 7,819
- 3
- 38
- 38
The way that I figured it on Linux to get the full name into a variable was:
u_id=`id -u`
uname=`awk -F: -vid=$u_id '{if ($3 == id) print $5}' /etc/passwd`
Then just simple use the variable, ex: $ echo $uname

- 13
- 4
Take 1:
$ user_name=sshd
$ awk -F: "\$1 == \"$user_name\" { print \$5 }" /etc/passwd
Secure Shell Daemon
However, passwd database supports special character '&' in the gecos, which should replaced with capitalized value of user name:
$ user_name=operator
$ awk -F: "\$1 == \"$user_name\" { print \$5 }" /etc/passwd
System &
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:
$ 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

- 71
- 4
The good old finger may also help :-)
finger $USER |head -n1 |cut -d : -f3

- 1,159
- 8
- 14
-
2OP already mentioned finger wasn't installed at least a year before yo posted this answer ;) – Scott Rowley Nov 22 '13 at 14:59