Why is the output from `groups` different from `groups user` if Im currently logged in as user?

It could be one of the following:

  • It could be a bug (although I doubt it)
  • You may need to logout and login again

The groups are set in the /etc/group.


Just as every process has a current real and effective user ID, and a real and effective group ID, it also has a list of supplementary groups. These are numbers (not names) all maintained by the kernel. They are set by the login process (or display manager) when you log it, just like your user ID. They are inherited by sub-processes, just like your user ID.

When you run groups with no arguments, it ultimately invokes getgroups() to obtain the supplementary group list from the kernel. (On my Linux system, /usr/bin/groups is a shell script that runs "id -Gn", which in turn invokes getgroups().)

When you run groups username, the command has to "guess" what the supplementary groups will be when that user logs in. It generally does this by reading /etc/group or talking to NIS or talking to nscd or... Well, there are a lot of ways it might work.

What you are observing is similar to discovering that your current real user ID and your entry in /etc/passwd are inconsistent. This means there is something a little odd about your system's configuration, but it is hard to say what without more investigation.


(Remark: The groups command, although still useful, is mostly superseded by the id command.)

A user has a primary group that is traditionally defined in the file /etc/passwd file with which he logs in, but that today may have other sources. He may also be a member of additional groups, known as secondary or supplementary groups, traditionally specified in the file /etc/groups, but which today can also come from or be implied by additional sources (such as NIS, LDAP, SAMBA etc).

Primary and supplementary groups are defined at the time of login and remain current. However, the user can at any time change his current active primary group by using the newgrp command.

The login process sets the primary and supplementary groups. For the later, it typically calls the libc function initgroups, which compiles the list of supplementary group data and passes it to the setgroups function, which establishes it in the context of the process.

The sources of information for initgroups are:

  • /etc/passwd for the primary login
  • /etc/groups for supplementary groups
  • /etc/nsswitch.conf for sources to supplementary groups, which is described as:

used by the GNU C Library and certain other applications to determine the sources from which to obtain name-service information in a range of categories, and in what order. Each category of information is identified by a database name.

The groups command shows the groups as currently applied to your user, and the list will start with the current primary group followed by the supplementary groups from the time of login. Any changes to the sources of the data from after the time of login are not reflected in the displayed list.

The groups username command is asking Linux to calculate the groups for that user, which it will do using principally the files /etc/password and /etc/groups and then the additional sources. This will reflect the current situation of the system files and may not equal the current groups that are still in effect from the time of login.

The groups username command may give a different result when it doesn't use all the sources that the login process used to calculate your supplementary groups, which is what apparently happened in your case. These sources may not be accessible from your login or may just not be consulted by the command.

Using the id username command may give better results, although also not guaranteed to be as complete as that of the login process. The id command is more recent than, and was intended to be more precise than, the old groups command.

While the groups command gives a precise and correct result, you have well demonstrated that the groups username command cannot be depended upon to do the same.

Without examining the source-code of the groups command, I would guess that the implementation of the groups username command in your Linux distribution analyzes /etc/groups, which in your case contained nothing, but does not use /etc/nsswitch.conf, from which came all of your supplementary groups. Therefore is listed only the primary group name, jacob.

For more information see:

  • credentials(7) - Linux man page
  • How to use nsswitch.conf to find Linux system information