LESSON 3 OF 4
Collect diagnostic evidence without mixing conclusions into it
Exit status is a separate signal
Commands normally return an exit status. Zero usually communicates successful completion according to that command's contract. Non-zero values communicate other outcomes; their precise meanings depend on the command. A successful cat proves that this process could read the specified file at that moment. It does not prove that the file contents are semantically correct or that a service loaded them.
Capture status immediately, because a later command can replace $?:
cat "$lab_dir/config/agent.conf"
read_status=$?
printf 'Configuration read status: %s\n' "$read_status"
Do not run printf first and then record its status as the result of cat. This is an easy way to produce an apparently clean diagnostic report after the operation you intended to check failed.
Standard output and standard error have different purposes
cat "$lab_dir/config/missing.conf" > "$lab_dir/logs/read-output.txt" 2> "$lab_dir/logs/read-error.txt"
read_status=$?
printf 'Missing-file status: %s\n' "$read_status"
wc -c "$lab_dir/logs/read-output.txt" "$lab_dir/logs/read-error.txt"
cat "$lab_dir/logs/read-error.txt"
The output file should be empty, the error file should contain a diagnostic, and the status should be non-zero. The exact error wording can depend on locale and implementation, so do not make your parser depend on one English sentence unless that is a documented interface.
> writes standard output to a file; 2> writes standard error. In this exercise the destinations are deliberate new lab files. A redirection can overwrite an existing file before the command succeeds. Do not treat output redirection as a harmless inspection operation when its destination contains valuable evidence.
The absence of normal output does not mean a command found no problems. It may have failed. A dependable collector preserves both outcome and diagnostic context.
A pipeline can conceal an upstream failure
Bash normally reports the exit status of the last command in a pipeline. A later command can succeed after an earlier command fails. In a subshell, compare the default behavior with pipefail:
(
false | cat
default_status=$?
set -o pipefail
false | cat
pipe_status=$?
printf 'Default=%s pipefail=%s\n' "$default_status" "$pipe_status"
)
Expected statuses are default 0 and pipefail non-zero. false is a deliberate failure command; cat can successfully consume the empty stream. The subshell keeps the changed shell option out of your parent session.
pipefail is a useful error boundary, not a complete error-handling strategy. A command may use a non-zero status for a normal negative result. grep, for example, distinguishes a match from no match and from an error. Your script must interpret the command's contract rather than declare every non-zero value a system incident.
Search logs with explicit context
grep -n -- 'ERROR' "$lab_dir/logs/agent.log"
printf 'Search status: %s\n' "$?"
grep -n -- 'TIMEOUT' "$lab_dir/logs/agent.log"
printf 'No-match status: %s\n' "$?"
The first search should report line 2 and status 0. The second should find no matching line and return status 1. Searching a nonexistent file should produce an error and a different status. These are three different observations.
The log fixture has no timestamps, process identifiers or request identifiers. It cannot establish an incident timeline or prove which service attempt emitted the error. A real log source needs those fields and an understood time zone. Keep the collection time separate from the event time.
Process evidence is a snapshot
A command such as ps can show current process identities and arguments. It cannot establish every process that ran yesterday. On Linux systems with the relevant tools, inspect a small snapshot:
ps -eo pid,user,comm --sort=pid | head -n 6
Results vary by environment. A short snapshot is an exercise in reading the fields, not a required process list. A process may start or exit while you inspect it; record the collection time and do not describe the snapshot as a permanent state.
Process arguments can contain sensitive information. Prefer a narrow set of fields for routine reporting. Do not paste a full diagnostic bundle into a public project submission. The course uses fictional paths and data so you can demonstrate the skill without exposing a work system.
Worked laboratory solution
Compare your reasoning with the worked solution
bob’s team membership gives directory read/execute and file read through group bits, so the stated path permits reading. agent has no matching group: the directory’s other bits are0, preventing traversal, and the file’s other bits also grant nothing. Root’s success is not evidence for the service identity. Inspect the actual service account and approved access requirement. A narrowly scoped group/permission design may be appropriate, but changing everything recursively to777 would expose more than required and obscure ownership intent.
YOUR NEXT STEP
Keep building your skills
No directly related CogniSkill book is mapped to this course yet. Continue with the free learning, or compare the publishing catalogue by your next goal.
Explore books by topic and goal →Sign in to save lesson completion. Reading position is separate from completion.
Practice notes — your working space
Save predictions, outputs and explanations as you work. Notes stay on this browser, not your account; people sharing this browser can access them. Avoid passwords and sensitive data. Export to keep a portable copy, or clear your notes before leaving a shared device.
How was this lesson?
Help us improve this lesson.