Script Basics & Variables
Anatomy of a Script
Scenario: You've now typed dozens of individual commands across this course. A shell script is nothing more mysterious than those same commands, saved into a file, so you can run the whole sequence with one word instead of retyping it every time - the natural next step once you're repeating yourself at the shell.
#!/bin/bash # shebang - which interpreter
set -euo pipefail # fail fast on errors & unset vars
name="world" # no spaces around =
echo "Hello, $name"
The very first line, #!/bin/bash, is called the shebang. It's not a comment the shell ignores - when you execute a file (rather than piping it into bash explicitly), the kernel reads this exact line to know which program should interpret the rest of the file. Without it, the system has no reliable way to know your script is meant for bash rather than, say, Python.
Make it executable and run it: chmod +x script.sh && ./script.sh - this connects directly back to the Permissions module: a script is just a text file, and the kernel refuses to run it as a program at all unless its execute bit is set.
| Variable | Meaning |
|---|---|
$0 | Script name |
$1, $2 … | Positional arguments |
$# | Number of arguments |
$@ | All arguments (as separate words) |
$? | Exit status of last command |
$ | Current PID |
These special variables are how a script reads what was typed after its own name on the command line. Run ./deploy.sh staging and inside the script, $1 is staging, $# is 1, and $0 is ./deploy.sh itself.
Command substitution (today=$(date +%F)) runs a command and captures its output into a variable instead of printing it to the screen. Arithmetic (count=$((count + 1))) is bash's syntax for doing math, since plain + between variables would otherwise just be string concatenation.
Tip: That second line,set -euo pipefail, is one of the highest-value habits in all of shell scripting, and it's worth understanding each letter:-emakes the entire script stop immediately the moment any single command fails (by default, bash just barrels on to the next line even after a failure - dangerous in something like a deployment script).-utreats using an unset variable as an error rather than silently substituting an empty string (which quietly hides typos like$HOEMinstead of$HOME).-o pipefailfixes a specific blind spot: normally a pipeline's exit status is only that of its last command, sofalse | truelooks like success even though the first command failed;pipefailmakes the whole pipeline fail if any stage does. Together, these three turn a script from "probably works" into "fails loudly the moment something's wrong," which is exactly what you want for anything touching production.