Shell Scripting — Automate Everything with Bash
1326 words
7 min read
Visual companion
Python
Type and operator map
Python Week 1: the first filter for runtime behavior
View
Revision summary
What this note is really saying
Short form
# Shell Scripting — Automate Everything with Bash ## 🎯 Learning Objectives - Write and execute bash scripts - Use variables, conditionals, and loops - Handle command-line arguments - Perform arithmetic operations - Handle errors and exit codes ## 1. What is Shell Scripting?

Shell Scripting — Automate Everything with Bash
🎯 Learning Objectives
- Write and execute bash scripts
- Use variables, conditionals, and loops
- Handle command-line arguments
- Perform arithmetic operations
- Handle errors and exit codes
1. What is Shell Scripting?
Shell scripting is writing a series of commands in a file to automate tasks. Instead of typing 10 commands manually, you write a script and run it once.
Example use cases:
- Backup automation
- Log rotation and cleanup
- Deployment scripts
- Data processing pipelines
- System monitoring
2. Your First Script
bash#!/bin/bash # This is a comment echo "Hello, World!" echo "Current directory: $(pwd)" echo "Current user: $USER"
Save and run:
bashchmod +x myscript.sh # Make executable ./myscript.sh # Run bash myscript.sh # Or run with bash
The shebang
#!/bin/bash: Tells the system which interpreter to use.3. Variables
bash#!/bin/bash # Assigning variables (no spaces around =) name="Alice" age=25 greeting="Hello, $name!" # Variable expansion with $ echo $name # Alice echo ${name} # Alice (braces useful for disambiguation) echo "Age: $age" # Age: 25 echo "$greeting" # Hello, Alice! # Command substitution current_dir=$(pwd) # Preferred syntax current_dir=`pwd` # Old syntax files_count=$(ls | wc -l) # Read-only and unset readonly PI=3.14159 # Cannot be changed unset name # Remove variable # Special variables echo $0 # Script name echo $1 # First argument echo $2 # Second argument echo $# # Number of arguments echo $@ # All arguments as separate words echo $* # All arguments as single string echo $? # Exit code of last command echo $$ # Process ID of current script
4. Arrays
bash#!/bin/bash # Declare array fruits=("apple" "banana" "cherry") numbers=(1 2 3 4 5) # Access elements echo ${fruits[0]} # apple echo ${fruits[1]} # banana echo ${fruits[@]} # All elements echo ${#fruits[@]} # Length (3) # Add element fruits+=("date") # Loop through array for fruit in "${fruits[@]}"; do echo "I like $fruit" done
5. Conditionals
bash#!/bin/bash # if-then-else if [ "$age" -ge 18 ]; then echo "Adult" else echo "Minor" fi # elif if [ "$score" -ge 90 ]; then echo "A" elif [ "$score" -ge 80 ]; then echo "B" elif [ "$score" -ge 70 ]; then echo "C" else echo "D" fi # File tests if [ -f "$filename" ]; then # File exists and is regular file echo "File exists" fi if [ -d "$dirname" ]; then # Directory exists echo "Directory exists" fi if [ -x "$file" ]; then # File is executable echo "File is executable" fi if [ -z "$str" ]; then # String is empty echo "Empty string" fi if [ -n "$str" ]; then # String is not empty echo "Non-empty string" fi # String comparison if [ "$name" = "Alice" ]; then # Equal (use single =) echo "Hello Alice" fi if [ "$name" != "Bob" ]; then # Not equal echo "Not Bob" fi # Numeric comparison if [ "$count" -eq 10 ]; then # Equal if [ "$count" -ne 10 ]; then # Not equal if [ "$count" -gt 10 ]; then # Greater than if [ "$count" -lt 10 ]; then # Less than if [ "$count" -ge 10 ]; then # Greater or equal if [ "$count" -le 10 ]; then # Less or equal # Logical operators if [ "$a" -gt 0 ] && [ "$a" -lt 10 ]; then # AND echo "Between 0 and 10" fi if [ "$a" -lt 0 ] || [ "$a" -gt 10 ]; then # OR echo "Outside range" fi # Double brackets (bash-specific, more powerful) if $name == A*; then # Pattern matching echo "Name starts with A" fi
6. Loops
bash#!/bin/bash # For loop (list) for color in red green blue; do echo "Color: $color" done # For loop (C-style) for ((i=0; i<5; i++)); do echo "Iteration $i" done # For loop (files) for file in *.txt; do echo "Processing $file" wc -l "$file" done # While loop count=0 while [ $count -lt 5 ]; do echo "Count: $count" ((count++)) done # Until loop (while false) count=0 until [ $count -ge 5 ]; do echo "Count: $count" ((count++)) done # Break and continue for i in {1..10}; do if [ $i -eq 5 ]; then continue # Skip 5 fi if [ $i -eq 8 ]; then break # Stop at 8 fi echo $i done # Output: 1 2 3 4 6 7
7. Functions
bash#!/bin/bash # Define function function greet() { local name=$1 # $1 is first argument to function echo "Hello, $name!" } say_hello() { # Alternative syntax echo "Hello, $1!" } greet "Alice" # Hello, Alice! greet "Bob" # Hello, Bob! # Function with return value add() { local sum=$(( $1 + $2 )) echo $sum # Return via stdout return 0 # Return status } result=$(add 5 3) # Capture output echo $result # 8 # Global vs local variables count=10 increment() { local count=5 # Local variable ((count++)) echo $count # 6 (local) } increment echo $count # 10 (global, unchanged)
8. Exit Codes and Error Handling
bash#!/bin/bash # Exit on error set -e # Exit on first error set -u # Treat unset variables as error set -x # Print commands before executing (debug) set -o pipefail # Fail if any command in pipeline fails # Check exit code if ! command_that_might_fail; then echo "Command failed!" exit 1 fi # Or use $? cp file.txt backup/ if [ $? -ne 0 ]; then echo "Backup failed!" exit 1 fi
9. Practice Questions
Q1: Write a script that prints "Hello, [name]!" where name is the first argument.bash#!/bin/bash name=${1:-"World"} echo "Hello, $name!"Q2: How do you check if a file exists before processing it?bashif [ -f "$filename" ]; then echo "Processing $filename" wc -l "$filename" else echo "File not found: $filename" exit 1 fiQ3: What does$@represent in a script?Answer: All command-line arguments as separate quoted words."$@"preserves spaces in arguments. Contrast with$*which treats all args as a single string. Q4: How do you loop through all .txt files in a directory?bashfor file in *.txt; do echo "Processing $file" doneQ5: What doesset -edo in a shell script?Answer: Causes the script to exit immediately if any command returns a non-zero exit status. Prevents the script from continuing after errors. Use with caution — some commands may exit non-zero for non-error conditions. Q6: Write a function that returns the sum of two numbers.bashsum() { echo $(( $1 + $2 )) } result=$(sum 10 20) echo $result # 30Q7: What's the difference between local and global variables in functions?Answer:localvariables are scoped to the function — they don't affect variables outside. Global variables persist after the function returns. By default, all variables in bash are global; uselocalto limit scope. Q8: Write a script that backs up all .txt files to a backup directory.bash#!/bin/bash backup_dir="backup_$(date +%Y%m%d)" mkdir -p "$backup_dir" for file in *.txt; do cp "$file" "$backup_dir/" echo "Backed up $file" done echo "Backup complete: $backup_dir"
📐 Key Concepts
| Concept | Syntax | Purpose |
|---|---|---|
| Variable | name="value" | Store data |
| Arguments | $1, $2, $@ | Access script parameters |
| If | if [ cond ]; then | Conditional execution |
| For | for i in list; do | Iteration |
| While | while [ cond ]; do | Condition-based loop |
| Function | function f() { } | Reusable code block |
| Exit | exit 0 / exit 1 | Return status |
| Arithmetic | $(( expr )) | Numeric operations |
🔗 Cross-References
- Next: Advanced Shell Scripting Join Discord Previous6.1 Process ManagementNext8.1 Advanced Shell Scripting