· about 35 minutes · runs on ubuntu-26.04-devops · unrated
An unrated lab. It runs on your machine with no account and no network, and everything about it — the faults, the checks, the hints and the reference solution — is in the repository. An attempt on it is recorded on your profile and never moves a rating: only rated labs do. Rated and unrated labs.
export-orders joins the day's order files from /srv/orders/*.csv into one compressed CSV,
/srv/exports/orders-<YYYY-MM-DD>.csv.gz. The warehouse importer picks up any file in
/srv/exports whose name matches orders-*.csv.gz, as soon as it appears.
On Tuesday the export was stopped half way by a deploy that restarted the box's jobs, and the
warehouse imported half a day of orders. On Thursday one order file could not be read; the export
said exported, and the file was short again. Someone also found a stale /tmp/export.tmp owned
by a colleague that made their own run fail.
What is expected, and graded — the grader runs export-orders itself, as an ordinary user, through
the EXPORT_SRC and EXPORT_DEST variables the script already reads:
id,sku,qty, then every row of every
file — and exits 0.SIGTERM in the middle of an export, it exits non-zero and leaves
nothing behind — not in the destination, not in the temporary directory.You have root through sudo. It must all still hold after a reboot.
The machine is checked, rebooted, and checked again. A check passes only if it passes both times.
| Check | Objective |
|---|---|
| 01_a_good_export_is_complete | Publish a file only when it is complete, in one step |
| 02_a_failed_export_leaves_nothing | Publish a file only when it is complete, in one step |
| 03_an_interrupted_export_leaves_nothing | Clean up after a script however it ends: success, failure or a signal |
| 04_two_exports_at_once | Keep two runs of the same script from sharing a temporary file |
Where the lab's hints send you, level by level, as you ask for them (h, then l opens a journal section in the TUI).
man 1 gzipman 1 bashman 7 signalman 1 mktemp4 questions on the same topic, in the lab's Theory tab. They never affect the lab's grade. Three of them, to answer here:
What does this print?
out=$(bash -c 'trap "echo cleaned" EXIT; kill -TERM $$; echo after')
echo "$out $?"
cleaned 143
Bash runs the EXIT trap when a fatal signal such as SIGTERM kills it, then dies of that signal, so the trap prints cleaned, the echo after never runs, and the status is 128 + 15 = 143. dash (/bin/sh on Ubuntu) does not run the EXIT trap on a signal, which is why a POSIX sh script traps the signals as well.
man 1 bash (SIGNALS; trap) · man 7 signal · executed in a sandbox
A bash script runs `trap 'echo stopping' TERM` and then a command that takes a minute. Ten seconds in, it receives SIGTERM. What happens?
It prints stopping when the command finishes, then carries on with the next line
Bash runs a trap for a signal only after the foreground command it is waiting for returns, and a trap that does not exit lets the script continue. Without a TERM trap, bash would have handled the signal at once (running any EXIT trap). A long command started in the background and waited for with wait is the way to make a trapped signal take effect immediately.
man 1 bash (SIGNALS)
An importer takes any `orders-*.csv.gz` in `/srv/exports` as soon as it appears. Which way of writing the export can never hand it a partial file?
gzip into /srv/exports/.orders.XXXXXX from mktemp, then mv it to the final name
A rename within one directory is atomic, and the partial file's name does not match the importer's pattern. Across file systems mv copies, which is visible while it happens. Writing to the final name exposes the file from its first byte, however carefully a failure is handled afterwards — and a signal can prevent that handling altogether.
man 2 rename · man 1 mktemp