Learning bite
Bash arguments and quoting
Preserve argument boundaries and make a script interface explicit.
Bash
Linux
Predict before you try
Can a script print a plausible report while losing the failure of an earlier command?
Try it: A shell runs commands and connects their results →On this page
A shell runs commands and connects their results
Bash reads a command, expands its arguments, finds the executable or built-in command, and runs it. A script stores those steps in a file. We will inspect paths, not change services. Run this module in Bash inside the Ubuntu machine; macOS's usual interactive Zsh is a different interpreter.
Create a new directory with mkdir -p ~/foundations-shell, then cd ~/foundations-shell. Use it only for this module's practice files. A variable assignment has no spaces around =:
study_name='file with spaces.txt'
printf 'sample\n' > "$study_name"
printf '<%s>\n' "$study_name"
printf '<%s>\n' $study_name
Expected output from the quoted form is one line, <file with spaces.txt>. The unquoted form produces three lines. Bash split the value into words before printf saw it; unquoted expansions may also expand wildcard patterns into filenames. Single quotes preserve literal characters. Double quotes allow variable expansion while preserving one argument. The value is data, so do not put it into a command string and run eval.
Give a script a clear interface
Save the following as inspect-path.sh in this directory. The quoted EOF prevents your current shell expanding variables while writing the script:
cat > inspect-path.sh <<'EOF'
#!/usr/bin/env bash
if [[ $# -ne 1 ]]; then
printf 'Usage: %s PATH\n' "$0" >&2
exit 2
fi
study_target=$1
if [[ ! -e "$study_target" ]]; then
printf 'Path does not exist: %s\n' "$study_target" >&2
exit 1
fi
printf 'Inspecting: %s\n' "$study_target"
ls -ld -- "$study_target"
EOF
bash inspect-path.sh "$study_name"
bash inspect-path.sh "$HOME"
$# is the argument count, $0 the script name, and $1 its first argument. An if runs the commands after then when its test returns status 0. [[ ... ]] is Bash's conditional syntax; -ne means numerically unequal, -e tests whether a path resolves to an existing object, and ! reverses the test. fi closes the conditional. We check the count before reading $1.
>&2 directs a message to the error stream. exit 2 ends this script with its chosen usage-error status; exit 1 reports a missing target. Otherwise the final ls status becomes the script status. -- ends options for ls, so a name beginning with - is treated as a path. A dangling symbolic link fails -e, and an existing file may disappear before ls; this check is not a lock.
You can also make the script executable with chmod u+x inspect-path.sh and run ./inspect-path.sh .. ./ supplies a path instead of asking Bash to find the program in PATH. The shebang selects Bash for direct execution; sh inspect-path.sh explicitly chooses another shell and may reject [[ ... ]].
Repeat a check without losing argument boundaries
A loop assigns each listed value to a variable and runs its body once per value:
for study_path in . 'file with spaces.txt' './missing-study-path'; do
if bash inspect-path.sh "$study_path"; then
printf 'Inspection succeeded\n'
else
printf 'Inspection failed\n' >&2
fi
done
Expect two successes and one missing-path failure. The spaces in the second path remain part of one argument. A function gives a group of commands a name:
inspect_many() {
local study_path
for study_path in "$@"; do
bash inspect-path.sh "$study_path"
done
}
inspect_many . 'file with spaces.txt'
local keeps the loop variable within the function. "$@" preserves each supplied argument separately; "$*" would combine them into one string. This simple function returns the last command's result, so it is not yet a complete all-inputs success check.
Try no arguments and two arguments, predicting which if runs. Both return usage status 2 without inspecting a path. Keep the script and spaced filename for the testing bite. Next, connect commands using streams and pipes.
Apply this to MicroBank
Use inspect-path.sh to inspect the MicroBank evidence directory or its harmless configuration-access fixture. Preserve quoted paths and capture the command status. Listing metadata is sufficient; the diagnostic need not print configuration values. Record the script’s one-path contract before expanding it into the capstone’s bounded local checks.
Keep this observation in the MicroBank readiness project.
Sources
Primary references: Bash quoting↗; Bash conditional expressions↗.
Prove what you learned
Inspect the result
Record input, stdout/stderr, exit status and an assertion for the selected case.
Explain it in your own words
Explain why your observation supports the stated outcome, and name one thing it does not prove.
Try a small variation
Add a path containing spaces or an empty-input case, predict the result, and keep cleanup scoped.
Your evidence should show
- Record the context/revision or label the work as a paper or prepared fixture.
- Compare the prediction with the actual result from “A shell runs commands and connects their results”.
- Record input, stdout/stderr, exit status and an assertion for the selected case.
- Explain the transfer challenge and retain the same verification question.
Hint
Trace arguments, quoting, exit status and the point where results are captured.
Answer guide: compare after predicting
Yes. Verify inputs and exit behaviour with the declared cases; output text alone is insufficient.
Compare this with your actual observation. A paper answer is useful reasoning practice; record execution separately.
Recall the permission and path checks the diagnostic depends on. Revisit the previous lesson.
Save the prediction, result and explanation ↓Your notes and evidence
Record observations, questions, or links to your work. Keep credentials out of your notes.
Back up or restore this path
Progress and notes stay in this browser. A backup contains only this learning path.