Shell Scripting & Automation
Writing shell scripts is a powerful way to automate tasks, combine commands, and create custom workflows. This page introduces core scripting concepts, syntax, and practical examples to help you get started with Bash-based automation.
1. Introduction
Linux shells, like Bash, Zsh, or Dash, allow you to interact with the system via commands. By placing commands in a file (a script), you can automate tasks repeatedly without retyping. Common use cases include:
- Regular backups
- System updates or cleanup
- Log parsing and reporting
- Continuous deployment pipelines
We’ll focus on Bash scripting since it’s installed by default on many distributions, but the concepts apply to other shells, too.
2. Basic Syntax
A Bash script typically begins with a
shebang
line pointing to the shell interpreter:
#!/usr/bin/env bash
Then you include commands, variables, and control structures (if, for, while) as needed.
Remember to make the script executable with chmod +x filename.sh
or run it
via bash filename.sh
.
Variables
Variables are assigned without spaces, e.g. MYVAR="Hello"
.
Access them with $MYVAR
. For example:
MYVAR="Hello World"
echo $MYVAR
Conditions & Loops
Bash supports if
-then
-else
blocks and loops like
for
, while
, until
:
if [ "$MYVAR" == "Hello World" ]; then
echo "Yes, it matches!"
else
echo "No, it doesn't."
fi
for FILE in /path/to/*; do
echo "Found $FILE"
done
3. Example Scripts
3a. Hello World
The simplest script to confirm your environment is set up:
#!/usr/bin/env bash
# hello.sh - a simple Hello World script
echo "Hello, Firebird Flight!"
Make it executable (chmod +x hello.sh
), then run ./hello.sh
.
3b. Simple Backup Script
Backs up a specified directory to a timestamped tar file:
#!/usr/bin/env bash
# backup.sh - backs up a directory to /tmp
SOURCE_DIR=$1
DEST_DIR="/tmp"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
BACKUP_FILENAME="backup-$(basename $SOURCE_DIR)-$TIMESTAMP.tar.gz"
if [ -z "$SOURCE_DIR" ]; then
echo "Usage: $0 /path/to/dir"
exit 1
fi
# Create the tarball
tar -czf "$DEST_DIR/$BACKUP_FILENAME" "$SOURCE_DIR"
if [ $? -eq 0 ]; then
echo "Backup of $SOURCE_DIR saved to $DEST_DIR/$BACKUP_FILENAME"
else
echo "Backup failed!"
exit 1
fi
Usage: ./backup.sh /var/www
, for example. The script
ensures you passed a directory path, then creates a compressed archive in /tmp
.
3c. Log Parsing Script
A simple script that searches /var/log/syslog
for a given keyword,
counting occurrences:
#!/usr/bin/env bash
# parse_logs.sh - searches syslog for a keyword
KEYWORD=$1
if [ -z "$KEYWORD" ]; then
echo "Usage: $0 [keyword]"
exit 1
fi
COUNT=$(grep -ic "$KEYWORD" /var/log/syslog 2>/dev/null)
if [ $? -eq 0 ]; then
echo "Found $COUNT occurrences of '$KEYWORD' in /var/log/syslog"
else
echo "Error reading /var/log/syslog"
exit 1
fi
Usage: ./parse_logs.sh error
might output “Found 12 occurrences of 'error'...”
4. Best Practices
- **Use `#!/usr/bin/env bash`** instead of a hard-coded path like `/bin/bash`. This ensures the script picks up the Bash interpreter in the user’s environment.
- **Check exit codes** (`$?`) after critical commands to detect failures early.
- **Quote variables** (`"$VAR"`) to handle spaces or special characters properly.
- **Add usage messages** and argument checks so users know how to run your script.
- **Comment your code** to explain tricky logic and keep a record of what each function does.
- **Test thoroughly**. Scripts can inadvertently remove files or break systems if not tested carefully.
5. Conclusion
Shell scripting bridges the gap between manual command usage and full-scale programming languages. Even simple scripts can save you hours by automating repetitive tasks. As you gain experience, you’ll create more robust scripts for backups, deployments, container orchestration, and more.
For advanced automation, consider integrating with cron jobs, systemd timers, or configuration management tools (e.g., Ansible) to manage your scripts at scale. Happy scripting!