为什么 /etc/passwd 中的 GECOS 列显示 4 个空字段,而不是根据 adduser 命令显示的 5 个?

为什么 /etc/passwd 中的 GECOS 列显示 4 个空字段,而不是根据 adduser 命令显示的 5 个?

只是好奇以下情况

adduser执行命令如下时:

sudo adduser optimusprime
Adding user `optimusprime' ...
Adding new group `optimusprime' (1015) ...
Adding new user `optimusprime' (1013) with group `optimusprime' ...
Creating home directory `/home/optimusprime' ...
Copying files from `/etc/skel' ...
New password: 
Retype new password: 
passwd: password updated successfully
Changing the user information for optimusprime
Enter the new value, or press ENTER for the default
    Full Name []: 
    Room Number []: 
    Work Phone []: 
    Home Phone []: 
    Other []: 
Is the information correct? [Y/n]

观察有 5选修的字段可用于写入数据。如果在执行命令时默认为空cat /etc/passwd,则该用户的记录将显示如下:

optimusprime:x:1013:1015:,,,:/home/optimusprime:/bin/bash

观察,,,GECOS 部分。它表示 4 个字段为 ,A,B,C,D而不是 5 个字段为A,B,C,D,E。为什么它们之间存在这种差异或不匹配?说实话,我预料到了

optimusprime:x:1013:1015:,,,,:/home/optimusprime:/bin/bash

这也代表了可通过命令使用的 5 个字段adduser

如果使用usermod以下命令:

sudo usermod -c "A,B,C,D,E" optimusprime

用户显示为:

optimusprime:x:1013:1015:A,B,C,D,E:/home/optimusprime:/bin/bash

我知道甚至可以通过usermod以下命令添加更多字段:

sudo usermod -c "A,B,C,D,E,F" optimusprime
sudo usermod -c "A,B,C,D,E,F,G" optimusprime

因此这些命令的执行分别体现如下

optimusprime:x:1013:1015:A,B,C,D,E,F:/home/optimusprime:/bin/bash
optimusprime:x:1013:1015:A,B,C,D,E,F,G:/home/optimusprime:/bin/bash

乍一看并不清楚 GECOS 最低限度是基于 4 个还是 5 个字段。

答案1

/etc/passwd 文件的手册页man 5 passwd在这方面特别简洁:

注释字段被各种系统实用程序使用,例如 finger(1)。

POSIX 也没什么帮助——事实上,POSIX 密码结构标准密码文件,根本不要求有 GECOS 或注释字段:

<pwd.h> 头文件应定义 struct passwd 结构,该结构至少应包括以下成员:

char    *pw_name   User's login name. 
uid_t    pw_uid    Numerical user ID. 
gid_t    pw_gid    Numerical group ID. 
char    *pw_dir    Initial working directory. 
char    *pw_shell  Program to use as shell.

如果我们查看/usr/include/pwd.h包提供的glibc 实现libc-dev,我们会发现它的pw_gecos成员是一个简单的 C 字符串(或指向字符的指针):

/* A record in the user database.  */
struct passwd
{
  char *pw_name;                /* Username.  */
  char *pw_passwd;              /* Hashed passphrase, if shadow database
                                   not in use (see shadow.h).  */
  __uid_t pw_uid;               /* User ID.  */
  __gid_t pw_gid;               /* Group ID.  */
  char *pw_gecos;               /* Real name.  */
  char *pw_dir;                 /* Home directory.  */
  char *pw_shell;               /* Shell program.  */
};

因此,任何使用 glibcgetpwent系列函数获取密码数据库信息的应用程序都将以单个字符串的形式获取结果 - 本质上由应用程序决定如何解析它。特别是,命令的 BSD 实现finger- 如果您finger从 Ubuntu安装,您将获得该命令宇宙存储库-使用以下方法标记字符串斯特雷普但仅分配最多 4 个以逗号分隔的子字段:

/*
 * fields[0] -> real name
 * fields[1] -> office
 * fields[2] -> officephone
 * fields[3] -> homephone
 */
nfields = 0;
while ((p = strsep(&bp, ","))) {
        if (nfields < 4) fields[nfields++] = *p ? p : NULL;
}
while (nfields<4) fields[nfields++] = NULL;

在 Ubuntu 中,/usr/sbin/adduser是一个使用系统的 perl 脚本chfn。如果你查看源代码chfn(来自 shadow passwd 套件),它会以类似的方式标记前四个子字段,然后将其余部分指定为“ slop”:

    /*
     * Anything left over is "slop".
     */
    if ((NULL != cp) && !oflg) {
            if ('\0' != slop[0]) {
                    strcat (slop, ",");
            }

            strcat (slop, cp);
    }

所以我猜结论是

  • GECOS 领域没有标准

  • 前 4 个子字段根据历史finger命令有常规解释

  • 此后的任何内容都是可选的,并取决于应用程序的解释。

相关内容