Objective. Students will write Bash scripts using variables, conditionals, loops, and functions to automate a defined development task.
This lesson, its worked examples and its practice questions has not yet been verified by an industry-certified professional or by a certification or approval body. It is a study draft and may contain errors. Do not use it as instructions for work on a job site or on live equipment. Always follow your instructor, your supervising professional, and current official references and regulations.
VoTechWorks program approval and accreditation are still in progress. Credentials are issued only by the certifying bodies named in each program, after their own exams.
A Bash script is a plain-text file containing a sequence of shell commands that the Bash interpreter executes in order. Scripts let you automate repetitive tasks — running tests, packaging files, checking system state before a deployment — so you spend less time typing the same commands and more time writing code. Every script you write for this course should be treated like production code: readable, commented, and tested before use.
The very first line of every Bash script must be the shebang:
```bash
#!/usr/bin/env bash
```
This tells the operating system which interpreter to use. Using `/usr/bin/env bash` rather than a hard-coded path like `/bin/bash` makes the script portable across Linux distributions where Bash may live in a different location.
After writing the script, make it executable:
```bash
chmod +x myscript.sh
```
Then run it with `./myscript.sh` or `bash myscript.sh`.
Variables store values you want to reuse. Assign them with no spaces around the equals sign:
```bash
SOURCE_DIR="/home/student/project"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
```
The `$(...)` syntax — called command substitution — runs the inner command and captures its output as a string. Reference a variable by prefixing it with `$`. Quoting variables with double quotes (`"$VARIABLE"`) prevents word-splitting errors when the value contains spaces.
Scripts can accept command-line arguments. Inside the script, `$1` is the first argument, `$2` the second, and so on. `$0` is the script's name itself. `$#` holds the total count of arguments. This lets you write flexible, reusable scripts:
```bash
SOURCE_DIR="$1"
```
Always validate arguments before using them — do not assume the caller provided a sane value.
The `if` statement tests a condition and branches accordingly:
```bash
if [ -d "$SOURCE_DIR" ]; then
echo "Directory found."
else
echo "ERROR: Directory does not exist." >&2
exit 1
fi
```
Common file-test operators:
For command output tests (like checking `git status`), capture the output and compare it as a string, or test the command's exit code directly with `if command; then`.
Send error messages to standard error with `>&2` so they do not pollute standard output.
Every command returns an exit code: `0` means success; any non-zero value means failure. Your scripts should follow the same convention. Use `exit 0` at the end for success and `exit 1` (or another non-zero value) when a precondition fails. Calling programs — CI/CD pipelines, deployment tools — rely on exit codes to know whether a script succeeded.
Bash provides `for`, `while`, and `until` loops. A common pattern iterates over a list:
```bash
for FILE in "$SOURCE_DIR"/*.conf; do
echo "Checking $FILE"
done
```
A `while` loop reads lines from a file or runs until a condition changes:
```bash
while IFS= read -r LINE; do
echo "$LINE"
done < input.txt
```
Functions group related commands under a name, reducing repetition:
```bash
check_port() {
local PORT="$1"
if ss -tuln | grep -q ":${PORT} "; then
echo "ERROR: Port $PORT is already in use." >&2
exit 1
fi
}
check_port 8080
```
Use `local` to keep variables inside the function, preventing accidental interference with the rest of the script.
For your `deploy_check.sh` lab, you will test three preconditions:
1. Git working tree is clean — `git status --porcelain` prints nothing when the tree is clean. Capture the output and test whether it is empty.
2. Config file exists — use `-f` to test for a regular file.
3. Port is not in use — `ss -tuln` lists listening TCP and UDP sockets. Pipe its output through `grep` to look for the port number.
Bash scripts run with the permissions of the user who executes them. A script run as root can modify or delete any file on the system. Follow these rules:
Answer each question, then check it. Nothing is recorded; this is your own practice.
A free tech program — complimentary, as our commitment to get America working. Help us build VoTechWorks. Tell us what works, what doesn’t, and what you want to learn.