grep1-7 Exercise 3: An Audit That Counts and Sets an Exit Status ================================================================= (Run in a fresh copy of the practice data from the chapter. Make it first with the block at the top of the chapter.) fails=0; missing=0 check() { # check FILE KEY EXPECTED if grep -qiE "^[[:space:]]*$2[[:space:]=]+$3[[:space:]]*(#.*)?$" "$1"; then echo "PASS $1: $2 = $3" elif grep -qiE "^[[:space:]]*$2([[:space:]=]|$)" "$1"; then echo "FAIL $1: $2 is set, but not to $3"; fails=$((fails + 1)) else echo "MISSING $1: $2 is not set"; missing=$((missing + 1)) fi } check etc/sshd_config PermitRootLogin no check etc/sshd_config PasswordAuthentication no check etc/sshd_config X11Forwarding no check etc/sshd_config PermitEmptyPasswords no check etc/sshd_config Port 22 check etc/sshd_config MaxAuthTries 4 echo echo "summary: $fails FAIL, $missing MISSING" if [ $((fails + missing)) -gt 0 ]; then exit 1; fi Output: FAIL etc/sshd_config: PermitRootLogin is set, but not to no FAIL etc/sshd_config: PasswordAuthentication is set, but not to no PASS etc/sshd_config: X11Forwarding = no MISSING etc/sshd_config: PermitEmptyPasswords is not set PASS etc/sshd_config: Port = 22 MISSING etc/sshd_config: MaxAuthTries is not set summary: 2 FAIL, 2 MISSING WHY THIS WORKS AS AN ANSWER --------------------------- The function is the same as in the chapter, with two counters that are only incremented in the FAIL and MISSING branches. The two extra checks: Port 22 passes (the line reads 'Port 22'), and MaxAuthTries is MISSING (the file never mentions it, so the default applies). The last line makes the script usable by other scripts: with any FAIL or MISSING it exits with 1 (the test uses arithmetic, [ $((fails + missing)) -gt 0 ]), otherwise it ends with 0. Because the output is on standard output and the verdict is in the exit status, it can be run from cron or a deployment script exactly like grep -q (Chapter 6). A limitation to remember: the key and value are put into the grep pattern as they are, so a setting whose value contains regular-expression characters (a dot, a plus) needs escaping or a different approach, and this check says nothing about a key set twice in the same file.