{ "id": "linux-shell-basics", "title": "Reading Exit Codes Like an Engineer", "category": "Linux Fundamentals", "isolation_type": "shared_namespace", "difficulty": "Easy", "type": "task", "weight": 3, "description": "## Reading Exit Codes Like an Engineer\n\nEvery command you run returns an exit code — `0` means success, anything else means failure. Scripts, CI pipelines, and Kubernetes probes all rely on this exact convention.\n\n**Your task:**\n\n1. Run a command that succeeds (e.g. `true`, or `ls` on a directory that exists) and save its exit code to `/srv/shell-lab/success-exit-code.txt`\n2. Run a command that fails (e.g. `ls` on a path that does NOT exist) and save its exit code to `/srv/shell-lab/fail-exit-code.txt`\n3. Look up the manual page for `ls` (`man ls`) and find one option you didn't know about", "hints": [ { "title": "Capturing an exit code", "body": "The special variable `$?` holds the exit code of the LAST command that ran — capture it immediately, before running anything else.", "command": "mkdir -p /srv/shell-lab\ntrue\necho $? > /srv/shell-lab/success-exit-code.txt\nls /this-path-does-not-exist 2>/dev/null\necho $? > /srv/shell-lab/fail-exit-code.txt" } ], "setup_commands": [ { "command": "mkdir -p /srv/shell-lab" } ], "validation": { "commands": [ { "description": "success-exit-code.txt records 0", "command": "cat /srv/shell-lab/success-exit-code.txt", "expected_output": "0", "match": "exact" }, { "description": "fail-exit-code.txt records a non-zero code", "command": "cat /srv/shell-lab/fail-exit-code.txt", "expected_output": "^[1-9][0-9]*$", "match": "regex" } ] }, "default_namespace": "default", "teardown_commands": [ { "command": "rm -rf /srv/shell-lab" } ] }