有人知道为什么 linux 命令
groups
显示的输出与
groups username
登录用户与参数用户名相同。例如:
thorsten@ubuntu:~/tmp$ groups
thorsten adm dialout cdrom plugdev lpadmin admin sambashare
thorsten@ubuntu:~/tmp$ groups thorsten
thorsten : thorsten adm dialout cdrom plugdev nogroup lpadmin admin sambashare
答案1
当您运行 时,它会在和中查找1给定的用户(尽管它可以是 LDAP、NIS 或其他2),并显示找到的所有组。groups username
/etc/passwd
/etc/group
另一方面,当你运行groups
不带任何参数的命令时,它只会列出所有组它本身属于3 – 即不必要与 中列出的相同/etc/group
。(请参阅下文了解解释。)事实上,仅有的进行的查找/etc/group
是为了将 GID 转换为组名。
每个进程都有一组证书,其中包含(除其他内容外)“真实组 ID”(主 GID)、“有效组 ID”(EGID)和“补充组”ID(辅助 GID)列表。默认情况下,进程从其父进程继承其凭据;但是,以 root(UID 0)身份运行或具有该CAP_SETUID
功能的进程可以设置任意凭据。
具体来说,当您登录 Linux(无论是通过 tty、X11 还是通过 SSH)时,登录过程(/bin/login、gdm、sshd)会查找您的用户名以确定您的 UID、主 GID 和辅助 GID。在个人计算机上,这仅意味着从和passwd
文件group
(或 NIS、LDAP 等)读取相应的行。
接下来,登录过程在开始会话之前切换4这些凭据,并且从现在开始您启动的每个过程都将具有完全相同的 UID 和 GID——系统不再检查/etc/group
5并且不会拾取所做的任何修改。
这样,该/usr/bin/groups
进程将属于与您相同的组当你登录时,而不是数据库所说的您所在的位置。
笔记:上述解释也适用于几乎所有的 Unix;对于 Windows NT 家族(除了 UID 和 GID 都称为“SID”,没有“主组”,凭证称为“进程令牌”,并且CAP_SETUID
是权限控制或者权限);并且可能适用于大多数其他多用户操作系统。
1 getpwuid() 和 getgrouplist() 用于查找用户的组。
2在 Linux 上,glibc 使用/etc/nsswitch.conf
来确定在哪里来查找这些信息。
3 groups
使用 getgid()、getegid() 和 getgroups() 来获取自己的凭证。
4 setuid()、setgid()、initgroups() 及相关函数。
5当然,也有例外,即在高架环境下运行的各种工具(设置用户标识),例如su
、sudo
、sg
、newgrp
、pkexec
等等。这意味着su $USER
将生成一个具有更新的组列表的 shell。
答案2
groups
它本身就给出了当前的进程所有者的组成员身份。这可能与groups <username>
进程启动后 groupdb 发生更改或进程所有者发生更改时不同。
答案3
只需重新启动计算机,组和组用户都应该得到相同的结果。
它们不同的原因是因为您在启动计算机时将自己添加到了一个您不是其成员的新组。
答案4
运行updatedb
,看看是否有变化。
当 groupdb 没有改变时,在我的 OSX 机器上也是一样的情况:
albert-hotspot:~ sami$ groups sami
staff com.apple.access_screensharing com.apple.sharepoint.group.2 everyone _appstore localaccounts _appserverusr admin _appserveradm _lpadmin _lpoperator _developer
albert-hotspot:~ sami$ groups
staff com.apple.access_screensharing com.apple.sharepoint.group.2 everyone _appstore localaccounts _appserverusr admin _appserveradm _lpadmin _lpoperator _developer
albert-hotspot:~ sami$