web-dev-qa-db-ja.com

Linux / POSIXシステムでユーザーのフルネームを取得する最も簡単な方法は何ですか?

/ etc/passwdを使ってgrepすることもできますが、それは面倒なようです。 'finger'がインストールされていません。その依存関係を回避したいと思います。これはプログラム用なので、ユーザー情報にアクセスするだけのコマンドがあると便利です。

36
Josh Gibson

プログラミング言語を指定しないので、シェルを使用することを想定します。これがPosixシェルの答えです。

これには2つのステップがあります。適切なレコードを取得してから、そのレコードから必要なフィールドを取得します。

まず、アカウントレコードの取得はpasswd tableのクエリによって行われます。

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

ヒステリックレーズンの場合、ユーザーのフルネームは“ GECOS”フィールドと呼ばれるフィールドに記録されます。問題を複雑にするために、このフィールドはしばしば完全な名前をいくつかのオプションのサブフィールドの1つとしてのみで独自の構造にしています。したがって、取引先レコードからフルネームを取得したい場合は、これらの両方のレベルを解析する必要があります。

$ 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フィールドを解析します。

47
bignose

最新のglibcシステムでは、次のコマンドを使用します。

_getent passwd "username" | cut -d ':' -f 5
_

これにより、基盤となるNSSモジュールとは関係なく、指定されたユーザーのpasswdエントリが取得されます。

のマンページgetent を読んでください。


すでにプログラミングしている場合は、getpwnam() C関数を使用できます。

_struct passwd *getpwnam(const char *name);
_

passwd構造体には、ユーザーのフルネームを含む_pw_gecos_メンバーがあります。

のマンページgetpwnam() を読んでください。


多くのシステムでは、ユーザーのフルネーム以上の目的でこのフィールドを使用していることに注意してください。最も一般的な規則は、フィールド内の区切り文字としてコンマ(_,_)を使用し、ユーザーの本名を最初に配置することです。

28
David Schmitt

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;
}
9
user25148

他の回答の組み合わせ、最小限のDebian/Ubuntuインストールでテスト:

getent passwd `whoami` | cut -d ':' -f 5 | cut -d ',' -f 1
8
Tombart

これを試して:

getent passwd eutl420 | awk -F':' '{gsub(",", "",$5); print $5}'
6
Rob L

上位2つの回答は1行で組み合わせることができます。

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

私のコードはbashとkshで動作しますが、ダッシュまたは古いBourne Shellでは動作しません。必要に応じて、他のフィールドも読み取ります。

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

/ etc/passwdファイル全体をスキャンすることもできます。これはプレーンなBourne Shellで1つのプロセスで機能しますが、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

一方、ツールを使用することは良いことです。そしてCもいいです。

2
Sam Watkins

フルネームを変数に入れるためにLinuxでそれを考え出した方法は次のとおりです。

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

次に、単に変数を使用します。例:$ echo $uname

0
TheTechCode