How to List Users in Linux (getent, passwd, who, id)

Tested on Ubuntu 26.04 LTS (Resolute Raccoon)
Applies to Ubuntu, Debian, Kali Linux, Linux Mint, Pop!_OS, Raspberry Pi OS, elementary OS, Zorin OS, Parrot OS, MX Linux, RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, Fedora, Arch Linux
Privilege read-only (no elevated privileges)
Scope List users in Linux with getent, /etc/passwd, who, and id.
Related guides list groups in Linux
create a user in Linux

You need a list of accounts on a box—every local name, human logins only, who is connected right now, or whether deploy already exists before you create it. Linux stores that data in /etc/passwd and exposes it through NSS tools such as getent, id, and who.

The commands below are the ones I reach for on Ubuntu and RHEL hosts. For group membership and listing members of sudo or docker, see list groups in Linux; for creating accounts, see create a user in Linux.


Quick reference

Task Command
List all users (recommended) getent passwd
Usernames only (local file) cut -d: -f1 /etc/passwd
Normal / human users Use UID_MIN — see below
System users (UID under UID_MIN) awk -F: -v min="$uid_min" '$3 < min {print $1}' /etc/passwd
Login-capable shells awk -F: '$7 ~ /\/(bash|sh|zsh)$/ {print $1}' /etc/passwd
Disabled / service shells awk -F: '$7 ~ /nologin|false/ {print $1}' /etc/passwd
Users with home directories awk -F: '{print $1, $6}' /etc/passwd
Homes under /home awk -F: '$6 ~ /^\/home\// {print $1, $6}' /etc/passwd
Count all NSS users getent passwd | wc -l
Check user exists getent passwd username then id username
Logged-in users (short) who or users
Logged-in users (detail) w or loginctl list-sessions
Recent login history last -a | head
Failed login attempts sudo lastb -a | head
User UID, GID, groups id username
Accounts with UID 0 awk -F: '($3 == 0) {print $1}' /etc/passwd
Sudo members (Debian/Ubuntu) getent group sudo
Sudo members (RHEL family) getent group wheel

List all users on the system

Use getent (preferred)

getent passwd asks NSS for every passwd entry—local /etc/passwd, systemd dynamic users, SSSD, LDAP, and anything else listed under passwd: in /etc/nsswitch.conf.

bash
getent passwd

Sample output (trimmed):

text
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
golinuxcloud:x:1000:1000:golinuxcloud:/home/golinuxcloud:/bin/bash
sshd:x:109:65534:sshd:/run/sshd:/usr/sbin/nologin

Each line is username:password_placeholder:UID:GID:gecos:home:shell. The x means hashed passwords live in /etc/shadow, not in this file.

Count how many passwd entries NSS returns:

bash
getent passwd | wc -l
text
52

Read /etc/passwd (local only)

cat /etc/passwd shows the local file. It is fine on a standalone laptop; on LDAP- or SSSD-backed hosts it can miss directory users that getent still finds.

bash
cut -d: -f1 /etc/passwd

Last few lines on this host:

text
golinuxcloud
vboxadd
sshd
pipewire
tomcat

Same usernames with awk:

bash
awk -F: '{print $1}' /etc/passwd

List users with compgen

compgen -u is a Bash builtin that lists usernames the shell knows about. It is handy for scripts but not a substitute for getent on NSS-heavy systems.

bash
compgen -u | tail -5
text
golinuxcloud
vboxadd
sshd
pipewire
tomcat

Normal users vs system accounts

System accounts (UID usually below 1000) run services—daemon, sshd, www-data. Normal users are human or application accounts you create for login; on Ubuntu the minimum UID is defined in /etc/login.defs:

bash
grep '^UID_MIN' /etc/login.defs
text
UID_MIN			 1000

List human-style accounts (excludes the nobody range at UID 65534):

bash
awk -F: '$3 >= 1000 && $3 < 65534 {print $1}' /etc/passwd
text
golinuxcloud

Use UID_MIN from /etc/login.defs

Instead of hardcoding 1000, read the system threshold:

bash
uid_min=$(awk '/^UID_MIN/ {print $2}' /etc/login.defs)

awk -F: -v min="$uid_min" '$3 >= min && $3 < 65534 {print $1}' /etc/passwd
text
golinuxcloud

This picks up local policy when UID_MIN is not 1000. List system accounts below that threshold:

bash
uid_min=$(awk '/^UID_MIN/ {print $2}' /etc/login.defs)
awk -F: -v min="$uid_min" '$3 < min {print $1}' /etc/passwd
text
root
daemon
bin
sys
sync
games
man
lp

RHEL and Debian both commonly set UID_MIN to 1000, but always read /etc/login.defs on the host you manage.


Login-capable accounts vs service accounts

Accounts with /bin/bash, /bin/sh, or /bin/zsh can log in interactively (if SSH and PAM allow it):

bash
awk -F: '$7 ~ /\/(bash|sh|zsh)$/ {print $1}' /etc/passwd
text
root
golinuxcloud

Service accounts often use /usr/sbin/nologin or /bin/false:

bash
awk -F: '$7 ~ /nologin|false/ {print $1}' /etc/passwd | head -6
text
daemon
bin
sys
games
man
lp

List users with home directories

Each passwd entry stores the home directory in field 6. Print usernames with their configured home:

bash
awk -F: '{print $1, $6}' /etc/passwd
text
root /root
daemon /usr/sbin
bin /bin
golinuxcloud /home/golinuxcloud

To list only accounts whose home is under /home:

bash
awk -F: '$6 ~ /^\/home\// {print $1, $6}' /etc/passwd
text
golinuxcloud /home/golinuxcloud

Useful when you are auditing manually created accounts, stale home directories, or orphaned /home folders after user deletion.


Users currently logged in

who, users, and w read session data from utmp—they show who is on the system right now, not every account in /etc/passwd.

w adds idle time and the current command:

bash
w
text
USER       TTY      FROM           LOGIN@   IDLE   JCPU   PCPU  WHAT
golinuxc   tty2     -              10:43    3:29m  0.11s  0.09s  /usr/libexec/gnome-session-init-worker ubuntu
golinuxc   pts/2    10.0.2.2       10:48    1:24m  0.13s  0.06s  sudo su -

users prints a single line of names; who adds terminal and source host when sessions are active.

On systemd-based hosts, loginctl complements who and w:

bash
loginctl list-users
loginctl list-sessions
text
UID USER         LINGER STATE
   0 root         no     active
1000 golinuxcloud no     active

2 users listed.
SESSION  UID USER         SEAT  LEADER CLASS   TTY  IDLE SINCE
      1 1000 golinuxcloud seat0 3061   user    tty2 yes  3h 27min ago
      2 1000 golinuxcloud -     3076   manager -    no   -

See recent user logins

who, users, and w show active sessions only. To review recent login history, use last:

bash
last -a | head

For failed login attempts on many distributions:

bash
sudo lastb -a | head

lastb reads /var/log/btmp and usually requires root. On newer minimal Ubuntu/Debian images, last may not be installed by default. On Ubuntu 26.04, install the wtmpdb package if you need login-history tooling:

bash
sudo apt install wtmpdb

Check whether a user exists

Before useradd or a deploy script, confirm the name is free. Start with NSS—works for local and directory users:

bash
getent passwd golinuxcloud
text
golinuxcloud:x:1000:1000:golinuxcloud:/home/golinuxcloud:/bin/bash

Then use id when you also need UID, GID, and group membership:

bash
id golinuxcloud
text
uid=1000(golinuxcloud) gid=1000(golinuxcloud) groups=1000(golinuxcloud),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),100(users),115(lpadmin)

When the account does not exist, both commands fail:

bash
getent passwd nonexistentuser; echo exit:$?
id nonexistentuser
text
exit:2
id: 'nonexistentuser': no such user

Local-file check only—use grep -x so root does not match rootless:

bash
grep -x '^golinuxcloud:' /etc/passwd

Users in a group

To see supplementary members of one group:

bash
getent group sudo
text
sudo:x:27:golinuxcloud

That fourth field is not the full membership picture—users can have a group as their primary GID without appearing there. For primary vs supplementary members, combined member lists, and getent vs /etc/group, use list groups in Linux.


NSS, LDAP, and directory users

On domain-joined hosts, directory users may never appear in /etc/passwd but still show up in getent passwd. Check which backends are configured:

bash
grep '^passwd:' /etc/nsswitch.conf
text
passwd:         files systemd sss

files is the local /etc/passwd; sss is SSSD; ldap or ad appear on other setups. When in doubt, trust getent passwd over cat /etc/passwd for a complete user list.


Privileged and sensitive accounts

Any account with UID 0 has full root privileges—there should usually be only one:

bash
awk -F: '($3 == 0) {print $1}' /etc/passwd
text
root

Debian and Ubuntu put sudo access in the sudo group:

bash
getent group sudo

RHEL, Rocky, and AlmaLinux typically use wheel instead:

bash
getent group wheel

On this Ubuntu host wheel is not defined locally—that is expected.


Troubleshooting

Problem Likely cause What to run
getent passwd missing LDAP users NSS not configured or SSSD down grep '^passwd:' /etc/nsswitch.conf; systemctl status sssd
cat /etc/passwd shorter than getent passwd Directory users not in local file Prefer getent passwd
id says no such user but user can SSH Typo or wrong NSS host getent passwd name; check /etc/hosts and SSSD logs
grep name /etc/passwd too many matches Substring match (root vs rootless) grep -x '^name:' /etc/passwd
who is empty but a process is running as that user The process is not an interactive login session, or utmp was not updated Try w, loginctl, or ps -u username; check /var/run/utmp
last command not found wtmp/utmp tools not installed on minimal image Install the distro package (e.g. apt install wtmpdb on Ubuntu 26.04) or use journalctl for SSH logs
No human users listed All UIDs below UID_MIN grep UID_MIN /etc/login.defs; adjust awk threshold
Unexpected UID 0 account Second root-equivalent user awk -F: '($3==0){print}' /etc/passwd — investigate immediately

References


Summary

Use getent passwd when you want every account NSS knows about; use cut or awk on /etc/passwd when you only care about local files. Filter human accounts with UID_MIN from /etc/login.defs, list homes with awk on field 6, see active sessions with w or loginctl, and check history with last. Confirm a username with getent passwd before id when directory users might be involved. For group membership detail, switch to list groups in Linux.


Frequently Asked Questions

1. How do I list all users in Linux?

Run getent passwd to list every user from all NSS sources (local files, systemd, SSSD, LDAP). For local accounts only, use cut -d: -f1 /etc/passwd or cat /etc/passwd.

2. What is the difference between getent passwd and cat /etc/passwd?

cat /etc/passwd reads the local file only. getent passwd queries the passwd database defined in /etc/nsswitch.conf, so it can include LDAP, SSSD, and other remote sources. Prefer getent on domain-joined or cloud-managed hosts.

3. How do I list only normal (human) users in Linux?

On many distros human accounts start at UID 1000. Run awk -F: '$3 >= 1000 && $3 < 65534 {print $1}' /etc/passwd, or read UID_MIN from /etc/login.defs and filter with that value.

4. How do I see who is logged in right now?

Run who for a short session list, users for names only, or w for login time, idle time, and the current command. On systemd hosts, loginctl list-sessions also shows active login sessions.

5. How do I check if a user exists in Linux?

Run getent passwd username first for NSS-aware checks, then id username for UID, GID, and groups. Exit status 0 and a passwd line mean the account exists. For local-only checks use grep -x '^username:' /etc/passwd.

6. Where are Linux user accounts stored?

Local account metadata lives in /etc/passwd (username, UID, GID, home, shell). Password hashes are in /etc/shadow. Centralized users appear through NSS when passwd: in /etc/nsswitch.conf includes sss, ldap, or similar.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.

  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security
  • Cloud Computing
  • Kubernetes
  • Linux
  • Ansible (software)