Reading a script before you run it
12 minThe shapes worth recognising
Five patterns that come back from a model and cost you something.
You do not have to read a generated script closely to catch most of what is wrong with it. Five shapes account for nearly all of it, and each one is visible at a glance once you have seen it named.
*A variable inside a path.* rm -rf "$DIR/build", cp $SRC $DST, chmod -R 777 $ROOT. Ask what the line becomes when the variable is empty, and remember that an unquoted empty variable does not leave an empty argument behind — it leaves nothing.
Try this
**A loop over the output of ls.** for f in $(ls *.txt) splits on whitespace, so a file called two words.txt becomes two loop iterations against two files that do not exist. for f in *.txt is shorter and correct, which is the unusual case where the fix costs nothing.
**A recursive chmod.** chmod -R 777 is almost never what was meant: it makes every file executable and world-writable, including the .env and the private key, and there is no undo because the modes it overwrote were not recorded anywhere.
Try this
Look at .env after that: mode 600 became 777. Nothing failed, nothing was printed, and the file is now readable by anyone on the machine.
*A fetch piped into a shell.* curl … | sh runs whatever that host returns, right now, with your privileges — and if the download is cut off half way, the shell runs the part that arrived. curl -o install.sh … and then reading it costs one line.
**A find with two patterns.** -o binds looser than the implicit -a, so an action written after an alternation belongs to one branch of it: find . -name '*.tmp' -o -name '*.log' -delete deletes the logs, leaves every .tmp file, and reports success.
Try this
Files
| Mode | Links | Size | Name |
|---|---|---|---|
| drwxr-xr-x | 4 | project/ | |
| -rw------- | 1 | 66 | .env |
| -rw-r--r-- | 1 | 42 | README.md |
| drwxr-xr-x | 2 | build/ | |
| -rw-r--r-- | 1 | 6 | cache.tmp |
| -rw-r--r-- | 1 | 9 | output.bin |
| -rw-r--r-- | 1 | 98 | notes.txt |
| drwxr-xr-x | 2 | src/ | |
| -rw-r--r-- | 1 | 29 | lib.sh |
| -rwxr-xr-x | 1 | 41 | main.sh |