DEV Community

dpm_bush
dpm_bush

Posted on Originally published at sshflow.com

How to Read the Linux User List Without Misreading It

A Linux account list is not a list of people currently using the machine. It includes service accounts, accounts from configured identity providers, and users who may not be logged in at all. The right command depends on which question you’re trying to answer.

Start with getent passwd

To list accounts the system knows about, run:

getent passwd
Enter fullscreen mode Exit fullscreen mode

Each result is a colon-separated record. For usernames only:

getent passwd | cut -d: -f1
Enter fullscreen mode Exit fullscreen mode

getent queries the system’s configured account sources. That commonly includes the local /etc/passwd file, and may also include directory services such as LDAP or SSSD. This makes it a better default when you want accounts visible to the system rather than just entries in one file.

If you specifically want local accounts, inspect the file directly:

cat /etc/passwd
Enter fullscreen mode Exit fullscreen mode

On a machine without another account source configured, these commands will usually return the same accounts. To see which sources are configured for the passwd database, check:

grep '^passwd' /etc/nsswitch.conf
Enter fullscreen mode Exit fullscreen mode

What does a passwd entry tell you?

A line from getent passwd or /etc/passwd has seven fields:

username:x:UID:GID:comment:home-directory:login-shell
Enter fullscreen mode Exit fullscreen mode

The fields are separated by colons. For example, the UID identifies the account, the GID is its primary group, and the final field is its login shell. The x is a placeholder; password hashes are stored separately in /etc/shadow.

A shell such as /usr/sbin/nologin or /bin/false is a strong clue that an account is not intended for interactive shell login. Service accounts often look like this, though the field alone doesn’t tell you everything about an account’s purpose or permissions.

The listing includes accounts regardless of whether they’re locked, expired, or currently being used. It answers “which accounts are known?”—not “who is online?”

Don’t assume UID 1000 means “a person”

A common shortcut is to treat every account with a UID of 1000 or higher as a human user. That threshold is not universal. Debian, Ubuntu, and RHEL 9+ commonly use 1000 as UID_MIN; older RHEL and CentOS releases used 500 by default, and administrators can change the setting.

Check the machine’s configured range:

grep -E '^(UID_MIN|UID_MAX)' /etc/login.defs
Enter fullscreen mode Exit fullscreen mode

Then use that value when filtering. This example reads UID_MIN and excludes UID 65534, conventionally used by the nobody account:

UID_MIN=$(awk '/^UID_MIN/{print $2}' /etc/login.defs)
getent passwd | awk -F: -v min="$UID_MIN" '$3 >= min && $3 != 65534'
Enter fullscreen mode Exit fullscreen mode

This is still a useful classification heuristic, not proof that every matching account belongs to a person. For a ready-made view, lslogins from util-linux can list regular or system accounts:

lslogins -u  # regular user accounts
lslogins -s  # system accounts
Enter fullscreen mode Exit fullscreen mode

Minimal installations may not have lslogins, so checking the configured UID threshold is a useful fallback. If you’re moving from inspection to account administration, creating a Linux user is a separate task with its own considerations.

Check one account instead of searching the whole list

To check whether a particular username is known to the system, query it directly:

getent passwd alice
Enter fullscreen mode Exit fullscreen mode

If the account exists, the command prints its record. If it doesn’t, there is no output and the command exits with status 2. That makes it practical in scripts:

if getent passwd alice > /dev/null; then
  echo "alice exists"
else
  echo "alice not found"
fi
Enter fullscreen mode Exit fullscreen mode

For an interactive check, id alice is another option. It displays the UID, GID, and group memberships, and reports an error if the account is not found. Like getent, it uses the configured account sources.

Account membership and active sessions are different questions

getent group developers displays a group record, including a list of supplementary members. That list may not include users whose primary group is developers. To check a specific user’s groups, including their primary group, use:

groups alice
# or
id -Gn alice
Enter fullscreen mode Exit fullscreen mode

There isn’t a single getent group output field that reliably gives every primary and supplementary member. For a broader look at group membership, see how Linux groups are listed.

To find out who has a login session right now, use session commands instead:

who    # username, terminal, and login time
w      # sessions plus system load and activity
users  # usernames in a single line
Enter fullscreen mode Exit fullscreen mode

These commands report active login sessions; they do not enumerate every account. A valid account won’t appear if nobody is logged in with it.

A quick way to choose

  • All accounts available to the system: getent passwd
  • Local-file accounts only: cat /etc/passwd
  • Usernames only: getent passwd | cut -d: -f1
  • Check whether one account exists: getent passwd username
  • Current login sessions: who or w

Keeping those distinctions in mind prevents two common mistakes: treating every account as a person, and treating the currently logged-in users as the complete account list.

I originally published a more detailed version of this guide on the SSHFlow blog.

I'm also building SSHFlow — an SSH client where every server gets its own workspace for terminals, SFTP, code, and databases.

Top comments (0)