| 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.
getent passwdSample output (trimmed):
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/nologinEach 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:
getent passwd | wc -l52Read /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.
cut -d: -f1 /etc/passwdLast few lines on this host:
golinuxcloud
vboxadd
sshd
pipewire
tomcatSame usernames with awk:
awk -F: '{print $1}' /etc/passwdList 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.
compgen -u | tail -5golinuxcloud
vboxadd
sshd
pipewire
tomcatNormal 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:
grep '^UID_MIN' /etc/login.defsUID_MIN 1000List human-style accounts (excludes the nobody range at UID 65534):
awk -F: '$3 >= 1000 && $3 < 65534 {print $1}' /etc/passwdgolinuxcloudUse UID_MIN from /etc/login.defs
Instead of hardcoding 1000, read the system threshold:
uid_min=$(awk '/^UID_MIN/ {print $2}' /etc/login.defs)
awk -F: -v min="$uid_min" '$3 >= min && $3 < 65534 {print $1}' /etc/passwdgolinuxcloudThis picks up local policy when UID_MIN is not 1000. List system accounts below that threshold:
uid_min=$(awk '/^UID_MIN/ {print $2}' /etc/login.defs)
awk -F: -v min="$uid_min" '$3 < min {print $1}' /etc/passwdroot
daemon
bin
sys
sync
games
man
lpRHEL 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):
awk -F: '$7 ~ /\/(bash|sh|zsh)$/ {print $1}' /etc/passwdroot
golinuxcloudService accounts often use /usr/sbin/nologin or /bin/false:
awk -F: '$7 ~ /nologin|false/ {print $1}' /etc/passwd | head -6daemon
bin
sys
games
man
lpList users with home directories
Each passwd entry stores the home directory in field 6. Print usernames with their configured home:
awk -F: '{print $1, $6}' /etc/passwdroot /root
daemon /usr/sbin
bin /bin
golinuxcloud /home/golinuxcloudTo list only accounts whose home is under /home:
awk -F: '$6 ~ /^\/home\// {print $1, $6}' /etc/passwdgolinuxcloud /home/golinuxcloudUseful 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:
wUSER 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:
loginctl list-users
loginctl list-sessionsUID 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:
last -a | headFor failed login attempts on many distributions:
sudo lastb -a | headlastb 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:
sudo apt install wtmpdbCheck whether a user exists
Before useradd or a deploy script, confirm the name is free. Start with NSS—works for local and directory users:
getent passwd golinuxcloudgolinuxcloud:x:1000:1000:golinuxcloud:/home/golinuxcloud:/bin/bashThen use id when you also need UID, GID, and group membership:
id golinuxclouduid=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:
getent passwd nonexistentuser; echo exit:$?
id nonexistentuserexit:2
id: 'nonexistentuser': no such userLocal-file check only—use grep -x so root does not match rootless:
grep -x '^golinuxcloud:' /etc/passwdUsers in a group
To see supplementary members of one group:
getent group sudosudo:x:27:golinuxcloudThat 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:
grep '^passwd:' /etc/nsswitch.confpasswd: files systemd sssfiles 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:
awk -F: '($3 == 0) {print $1}' /etc/passwdrootDebian and Ubuntu put sudo access in the sudo group:
getent group sudoRHEL, Rocky, and AlmaLinux typically use wheel instead:
getent group wheelOn 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
- getent(1) — get entries from NSS databases
- passwd(5) — password file format
- id(1)
- who(1)
- last(1)
- nsswitch.conf(5)
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.

