Three reports out of /etc/passwd.
grep, awk, sed, cut, sort, uniq.
A quarterly access audit needs the regular users, the top login shells, and the locked accounts pulled out of the system files, plus an in-place edit to a config that cannot be broken.
The ticket: auditor1 needs three reports out of /etc/passwd for the Q2 access audit. Every regular user with UID and shell, the three most common login shells with counts, and every account whose password is locked. Save them in /srv/audit_reports/. Also, /etc/motd.bak has the wrong company name throughout, and every “OldCorp” needs to become “Server1 Corp” in place, without breaking the file.
The real problem: nothing here is hard once you use the right tool for each slice. The exam loves asking for one specific column of a system file, so this is core muscle.
What we are doing: grep, awk, sed, cut, sort, and uniq on real system files, plus a safe in-place edit.
The ticket
id auditor1 # UID 3502 ls -ld /srv/audit_reports 2>/dev/null || sudo mkdir -p /srv/audit_reports
Concept review. One tool per job.
Read the manual pages, then match the tool to the task. /etc/passwd is colon delimited, which is why the field tools shine here.
man grep man awk man sed man cut
grep filter the lines that match a pattern awk field-based processing, conditionals, math, formatting sed stream editing, find and replace, in-place edits cut pull columns out by delimiter sort order lines, alphabetically or numerically uniq collapse or count adjacent duplicate lines (needs sorted input)
The field layout you are slicing: user:x:UID:GID:comment:home:shell.
Report one. Regular users.
Real users start at UID 1000. Filter on the third field and print the fields you want, formatted so the auditor can read it.
# see it first
awk -F: '$3 >= 1000 {print $1, $3, $7}' /etc/passwd
# aligned columns, saved to the report
sudo mkdir -p /srv/audit_reports
sudo chown admin:auditors /srv/audit_reports
sudo chmod 770 /srv/audit_reports
awk -F: '$3 >= 1000 {printf "%-20s %-6s %s\n", $1, $3, $7}' /etc/passwd \
| sudo tee /srv/audit_reports/regular_users.txt
sudo chgrp auditors /srv/audit_reports/regular_users.txt-F: sets the delimiter, $3 is the UID, $1 the name, $7 the shell. printf keeps the columns lined up.
Report two. The top three shells.
Build this one pipe at a time so you can watch it take shape. The order is deliberate, because uniq -c only collapses adjacent duplicates and needs sorted input.
cut -d: -f7 /etc/passwd # every shell cut -d: -f7 /etc/passwd | sort # sorted so duplicates sit together cut -d: -f7 /etc/passwd | sort | uniq -c # counted cut -d: -f7 /etc/passwd | sort | uniq -c | sort -rn | head -3 # top three # save it cut -d: -f7 /etc/passwd | sort | uniq -c | sort -rn | head -3 \ | sudo tee /srv/audit_reports/top_shells.txt sudo chgrp auditors /srv/audit_reports/top_shells.txt
Report three. Locked accounts.
The password hash lives in /etc/shadow, not /etc/passwd, and a locked account has a leading ! on the hash. This needs sudo to read.
sudo awk -F: '$2 ~ /^!/ {print $1}' /etc/shadow \
| sudo tee /srv/audit_reports/locked_accounts.txt
sudo chgrp auditors /srv/audit_reports/locked_accounts.txt
sudo chmod 640 /srv/audit_reports/locked_accounts.txt # shadow-derived, keep it tight$2 ~ /^!/ is an awk regex match: field two begins with !. Because it comes from shadow, lock the report down to the auditors group.
The in-place edit, done safely
sed -i edits the file directly, which is exactly what is asked, and exactly what bites people who skip a backup. Always copy first.
# build the test file sudo bash -c 'cat > /etc/motd.bak << EOF Welcome to OldCorp Production Server For support, contact OldCorp IT This system is property of OldCorp. EOF' # back up, then replace globally, in place, then diff to confirm sudo cp /etc/motd.bak /etc/motd.bak.backup sudo sed -i 's/OldCorp/Server1 Corp/g' /etc/motd.bak sudo diff /etc/motd.bak.backup /etc/motd.bak
s/old/new/g substitutes every match on each line, and the diff against the backup proves you changed only what you meant to.
grep power moves
A handful of grep flags that come up constantly.
grep -i "root" /etc/passwd # case insensitive grep -E "bash|zsh" /etc/passwd # extended regex, alternatives grep -v "nologin" /etc/passwd # invert, lines that do NOT match sudo grep -r "PermitRootLogin" /etc/ssh/ # recursive across files grep -n "root" /etc/passwd # show line numbers grep -c "bash" /etc/passwd # count matching lines
Exam questions
Write the command first.
Q1. Print username and home directory side by side for all regular users (UID 1000 and up).
Q2. List all users whose shell is /bin/bash, showing username and UID, sorted numerically by UID.
Q3. Replace every OldCorp with Server1 Corp in /etc/motd.bak in place, showing the file before and after.
Answers.
# A1
awk -F: '$3 >= 1000 {print $1, $6}' /etc/passwd
# A2
awk -F: '$7 == "/bin/bash" {print $1, $3}' /etc/passwd | sort -k2 -n
# A3
sudo cat /etc/motd.bak
sudo sed -i 's/OldCorp/Server1 Corp/g' /etc/motd.bak
sudo cat /etc/motd.bakFinal checklist: confirm everything works
If every check passes, the ticket is done.
# 1. all three reports exist ls -l /srv/audit_reports/regular_users.txt /srv/audit_reports/top_shells.txt /srv/audit_reports/locked_accounts.txt # 2. no OldCorp left in the motd grep -c OldCorp /etc/motd.bak # expect 0 # 3. locked report is auditors-only (640) ls -l /srv/audit_reports/locked_accounts.txt # 4. all three exam commands written from scratch # 5. tracker entry checked off
Reply to auditor1: all three reports are in /srv/audit_reports/, the locked-accounts one restricted to the auditors group, and /etc/motd.bak is updated, backed up before the edit and verified with diff.