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

前端 未结 10 1413
旧时难觅i
旧时难觅i 2021-01-31 08:29

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

相关标签:
10条回答
  • 2021-01-31 08:39

    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;
    }
    
    0 讨论(0)
  • 2021-01-31 08:43

    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.

    0 讨论(0)
  • 2021-01-31 08:43

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

    getent passwd `whoami` | cut -d ':' -f 5 | cut -d ',' -f 1
    
    0 讨论(0)
  • 2021-01-31 08:43

    The good old finger may also help :-)

    finger $USER |head -n1 |cut -d : -f3
    
    0 讨论(0)
  • 2021-01-31 08:51

    Try this:

    getent passwd eutl420 | awk -F':' '{gsub(",", "",$5); print $5}'
    
    0 讨论(0)
  • 2021-01-31 08:54

    The top two answers can be combined in one line:

    getent passwd <username> | cut -d ':' -f 5 | cut -d ',' -f 1
    
    0 讨论(0)
提交回复
热议问题