Linux Basic — Advanced Scripting Practice
Practice Exercises — Advanced Scripting
Solve these without temp files. Most should be one pipeline or a tight 5–10 line script.
Warm-up
- Templated config. Use a heredoc to generate
/tmp/app.confcontaining the current user, hostname, and date. - No-expansion heredoc. Print a literal
$PATHand a literal$(date)to a file without expansion. - Indented heredoc. Use
<<-EOFinside anifblock so the body is tab-indented but stripped on output. - Quick math. Compute
pi = 22/7to 6 decimal places usingbc -l <<<.
Here-Strings
- Parse without subshell. Take the string
"alice:1001:/home/alice"and split intouser,uid,homeusingIFS=:andread <<<. Print all three after the read. - Regex test. Validate that
"192.168.1.10"looks like an IPv4 usinggrep -Eqand a here-string. Printvalidorinvalid. - Pipe vs herestring. Show the difference: read into a variable using
echo x | read v; echo "$v"and thenread v <<< "x"; echo "$v". Explain why one is empty.
Process Substitution
- Diff two listings.
diff <(ls dir1)against<(ls dir2). Create the dirs first with a few overlapping filenames. - Common lines only. Use
comm -12 <(sort fileA) <(sort fileB)to print lines present in both. - Tee-split. Generate
seq 1 1000and split it:>(wc -l > /tmp/n)AND>(sha256sum > /tmp/h), sending raw output to/dev/null. Cat both result files. - Live config drift (simulated).
diff <(cat /etc/hostname)against<(echo "$HOSTNAME"). Should be identical.
Subshells & Grouping
- Isolated cd. Show
pwd, run( cd /tmp && pwd ), showpwdagain. The outer pwd must not change. - One redirect for many. Group three
echocalls with{ ; }and redirect once toout.log. - Strict-mode block. Wrap a critical 3-command section in
( set -euo pipefail; ... )so the surrounding script keeps lax settings. - The pipe-loses-variable trap. Count files matching
*.logusingls *.log | while read f; do ((n++)); done; echo "$n". Show whynis 0, then fix it using< <(...).
eval / coproc / exec
- Indirect variable (modern). Set
name="foo"andfoo="hello", then printhellousing${!name}(noeval). - Script-wide log. Add
exec > /tmp/run.log 2>&1to the top of a script and confirm all subsequentechos appear in the log instead of the terminal. - Open fd 3. Open
fd 3for writing to/tmp/three.log, send three lines to it with>&3, then close it. - Wrapper handoff. Write a wrapper that exports
MYAPP_ENV=prodthenexecs/usr/bin/env(so you can verify the env var in its output). - Coprocess calculator. Start
coproc BC { bc -l; }, send three expressions, read each answer, then close cleanly.
Stretch
- Heredoc-based SQL. Build a
psql -d $DB <<SQL ... SQLblock that takes a$user_idvariable and selects from a table — make sure the variable expands but a literal$$(dollar-quote) does not. - Generate then patch. Create
original.txtandmodified.txt, then applypatch original.txt <(diff -u original.txt modified.txt)sooriginal.txtends up matchingmodified.txt. - Multi-source env. Source two env files at once:
source <(cat a.env b.env). Then prove both sets of vars are present.
Verification Checklist
- No temporary files in any solution that uses process substitution
- No
evalunless explicitly required (and never with untrusted input) - All heredocs end with a flush-left delimiter
- The
exec > logtest still leaves stderr captured (because of2>&1) - The
while read | pipefix uses< <(...), notshopt -s lastpipe(unless you also disable job control)
Next chapter → Regular Expressions