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?

Answer choices

  • A. They are identical in all contexts

  • B. `$*` expands all arguments as a single word when quoted; `$@` expands each argument as a separate quoted word (Correct)

  • C. `$*` holds the argument count; `$@` holds the argument values

  • D. `$@` is deprecated; `$*` is the current standard

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?

Answer choices

  • A. It is a comment explaining which shell to use

  • B. It tells the OS which interpreter to use to execute the script (Correct)

  • C. It sets the bash version for compatibility

  • D. It grants execute permission to the script file

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.