Text preview & study summary
Bash Shell Scripting Fundamentals
A free sample of 5 questions from this quiz, shown in full with answer choices and explanations. No interactivity — everything is visible on this page for study and review.
Want to test your knowledge? Launch the Interactive Exam Simulator
Question 1
In Bash, `[[blank1]] -eq 0` checks if a command succeeded (tests the exit code), and the construct `cmd1 [[blank2]] cmd2` executes cmd2 ONLY if cmd1 fails (non-zero exit code).
Explanation
`$?` holds the last exit code: `grep "pattern" file.txt; if [ $? -eq 0 ]; then echo "Found"; fi`. Better idiom: `if grep -q "pattern" file.txt; then echo "Found"; fi`. The `||` operator: `mkdir /new/dir || exit 1` (exit if mkdir fails). `&&` operator: `mkdir /new/dir && echo "Created"` (echo only if mkdir succeeds). Combined: `cmd1 && cmd2 || cmd3` (cmd2 if cmd1 succeeds; cmd3 otherwise — but this has edge cases). Best practice: `set -e` (exit on error), `set -u` (error on undefined variables), `set -o pipefail` (pipe failures propagate) at script top for robust error handling.
Question 2
In Bash, `$(command)` is used for [[blank1]], allowing the output of a command to be captured and used as a value in another command or variable assignment.
Explanation
Command substitution captures a command's stdout: `today=$(date +%Y-%m-%d)` stores today's date in `$today`. `files=$(ls *.txt)` stores file listing. Nested: `echo "Uptime: $(uptime -p)"`. The backtick syntax `` `command` `` is equivalent but `$(...)` is preferred because: it's easier to nest, easier to read, more consistent with `${variable}` syntax. Process substitution `<(cmd)` is related but different — it creates a temporary file descriptor. Command substitution captures stdout; stderr still displays unless redirected: `output=$(command 2>&1)` captures both.
Question 3
In Bash, what is the difference between `$*` and `$@` when referencing all script arguments?
Explanation
The difference matters when arguments contain spaces: `"$*"` — joins all args with first IFS character as separator: `"arg1 arg2 arg3"` (one string). `"$@"` — each arg is individually quoted and separate: `"arg1" "arg2" "arg3"`. Example: script called with `./script.sh "file one.txt" "file two.txt"`: `for f in "$@"` — correctly processes two files; `for f in "$*"` — treats all as one string, broken. ALWAYS use `"$@"` when passing arguments to another command or iterating: `process_files "$@"`. `$#` = argument count; `$0` = script name; `$1`, `$2`, etc. = individual arguments.
Question 4
What is the purpose of the shebang line `#!/bin/bash` at the beginning of a shell script?
Explanation
The shebang (hashbang) `#!` on the first line followed by an interpreter path tells the OS which program to use when executing the file. `#!/bin/bash` → use bash; `#!/usr/bin/env python3` → find python3 in PATH; `#!/bin/sh` → POSIX-compatible shell. When you run `./script.sh`, the kernel reads the shebang and executes `/bin/bash ./script.sh`. Without a shebang, the current shell interprets the script (which may not be bash). The shebang IS a comment syntactically but functionally an interpreter directive. Execute permission is granted separately with `chmod +x script.sh`.
Question 5
The Bash command `[[blank1]] 0 23 * * 1-5 /opt/scripts/backup.sh` would schedule a cron job to run the backup script at 11 PM (23:00) on weekdays (Monday through Friday).
Explanation
Cron syntax: `minute hour day-of-month month day-of-week command`. Fields: minute (0-59), hour (0-23), day of month (1-31), month (1-12), day of week (0-7, where 0 and 7 = Sunday). `*` = every. Ranges: `1-5` = Monday through Friday. Lists: `1,3,5` = Mon, Wed, Fri. Steps: `*/5` = every 5 minutes. `0 23 * * 1-5` = minute 0, hour 23, any day of month, any month, weekdays 1-5 = 11 PM on Mon-Fri. `crontab -e` edits current user's crontab; `crontab -l` lists it. System-wide crons: `/etc/cron.d/`, `/etc/cron.daily/`. Use full paths in cron commands.
