Bash and Linux

List users whose login shell is bash

easyawk and cut Must-do

Problem statement

During a server hardening review you need the accounts that can get an interactive bash shell. /etc/passwd has seven colon-separated fields, and the seventh is the login shell. Print the username (field 1) of every account whose shell is exactly /bin/bash.

passwd

TEXT
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
deploy:x:1001:1001:Deploy User:/home/deploy:/bin/bash
postgres:x:112:120:PostgreSQL administrator:/var/lib/postgresql:/bin/bash
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync

Examples

Example 1

Input: Run the command on `passwd` (use `/etc/passwd` on a real host).

Output: root deploy postgres

Hints

Approach

-F: tells awk to split each line on colons, so $1 is the username and $7 the shell. The pattern $7 == "/bin/bash" is an exact string comparison on the shell field only, so a home directory or comment that happens to contain /bin/bash cannot cause a false match. The action {print $1} runs only for lines where the pattern is true. The awk program is in single quotes so the shell does not expand $7 and $1.

Bash
awk -F: '$7 == "/bin/bash" {print $1}' passwd

Follow-up questions

  • How would you list every account that can log in at all, i.e. whose shell is not nologin or false?
  • On a host using LDAP, why might /etc/passwd be incomplete? (getent passwd)

Frequently asked questions

cut is fine for picking fields when the delimiter is a single fixed character, like : here. It cannot filter rows, compare values, or handle runs of spaces as one separator. For whitespace-aligned output such as ps or df, use awk, whose default separator treats any run of spaces or tabs as one.