Introduction to Bash scripting
Table of contents
- What is a Bash script?
- The shebang
- Creating and running a script
- Command-line arguments
- Comments and documentation
- Practical exercises
1 - What is a Bash script?
Definition
A Bash script is a text file containing a sequence of commands that the shell executes automatically.
Benefits of scripting
| Benefit | Description |
|---|---|
| Automation | Repeat tasks without intervention |
| Reproducibility | Same result on every run |
| Documentation | The code documents the procedure |
| Efficiency | Faster execution than doing it by hand |
| Portability | Works on all Unix systems |
Use cases
- Automated backups
- Application deployment
- Server configuration
- Monitoring and alerts
- Batch file processing
🔝 Back to table of contents
2 - The shebang
What is the shebang?
The shebang (or hashbang) is the first line of a script that tells the system which interpreter to use.
#!/bin/bash
Anatomy
#! /bin/bash
│ │
│ └── Path to the interpreter
└── Magic characters (shebang)
Common variants
| Shebang | Interpreter |
|---|---|
#!/bin/bash | Bash (fixed path) |
#!/usr/bin/env bash | Bash (portable) |
#!/bin/sh | POSIX shell |
#!/usr/bin/env python3 | Python 3 |
#!/usr/bin/env node | Node.js |
Recommendation
Use #!/usr/bin/env bash for better portability. env looks up bash in the PATH.
Why the shebang matters
# Without a shebang
cat script.sh | sh # Interpreted by sh
./script.sh # Uses the current shell
# With shebang #!/bin/bash
./script.sh # Always interpreted by bash
🔝 Back to table of contents
3 - Creating and running a script
Create a script
# 1. Create the file
nano mon_script.sh
# 2. Add the content
#!/bin/bash
echo "Hello, World!"
echo "Date: $(date)"
echo "Utilisateur: $USER"
Make it executable
# Add execute permission
chmod +x mon_script.sh
# Check
ls -l mon_script.sh
# -rwxr-xr-x 1 user user 100 Jan 15 mon_script.sh
Execution methods
# 1. Direct execution (requires chmod +x)
./mon_script.sh
# 2. Via the interpreter (no chmod +x needed)
bash mon_script.sh
# 3. With source (runs in the current shell)
source mon_script.sh
# or
. mon_script.sh
Difference between ./script.sh and source script.sh
| Method | Environment | Variables |
|---|---|---|
./script.sh | New process | Not inherited |
source script.sh | Current shell | Inherited |
# Example
# script.sh contains: export MA_VAR="test"
./script.sh
echo $MA_VAR # Empty (variable in subshell)
source script.sh
echo $MA_VAR # "test" (variable in current shell)
First complete script
#!/bin/bash
# My first script
# Author: Your name
# Date: 2024-01-15
# Display a welcome message
echo "==================================="
echo " Bienvenue dans mon script !"
echo "==================================="
# System information
echo ""
echo "Informations système :"
echo " - Utilisateur : $USER"
echo " - Répertoire : $(pwd)"
echo " - Date : $(date '+%Y-%m-%d %H:%M')"
echo " - Hostname : $(hostname)"
echo ""
echo "Script terminé avec succès !"
🔝 Back to table of contents
4 - Command-line arguments
Special variables
| Variable | Meaning |
|---|---|
$0 | Script name |
$1, $2... | Arguments 1, 2... |
$# | Number of arguments |
$@ | All arguments (separate) |
$* | All arguments (single string) |
$$ | Script PID |
$? | Return code of the last command |
Example
#!/bin/bash
# args_demo.sh
echo "Nom du script : $0"
echo "Premier argument : $1"
echo "Deuxième argument : $2"
echo "Nombre d'arguments : $#"
echo "Tous les arguments : $@"
./args_demo.sh hello world 123
# Nom du script : ./args_demo.sh
# Premier argument : hello
# Deuxième argument : world
# Nombre d'arguments : 3
# Tous les arguments : hello world 123
Check the arguments
#!/bin/bash
# Make sure we have at least one argument
if [ $# -eq 0 ]; then
echo "Usage: $0 <nom>"
exit 1
fi
echo "Bonjour, $1 !"
Difference between $@ and $*
#!/bin/bash
# test_args.sh
echo "Avec \$@:"
for arg in "$@"; do
echo " - '$arg'"
done
echo "Avec \$*:"
for arg in "$*"; do
echo " - '$arg'"
done
./test_args.sh "hello world" "foo bar"
# Avec $@:
# - 'hello world'
# - 'foo bar'
# Avec $*:
# - 'hello world foo bar'
tip
Always use "$@" (with quotes) to preserve spaces within arguments.
🔝 Back to table of contents
5 - Comments and documentation
Simple comments
# This is a single-line comment
echo "Hello" # End-of-line comment
Script header
#!/bin/bash
#
# Name: backup.sh
# Description: Automatic backup script
# Author: Jean Dupont
# Date: 2024-01-15
# Version: 1.0
#
# Usage: ./backup.sh [source] [destination]
#
# Examples:
# ./backup.sh /var/www /backup
# ./backup.sh ~/Documents /mnt/usb
#
# Script code...
Document the sections
#!/bin/bash
#######################
# Configuration
#######################
BACKUP_DIR="/backup"
LOG_FILE="/var/log/backup.log"
#######################
# Functions
#######################
# Function: log_message
# Description: Writes a message to the log file
# Arguments: $1 - message to log
log_message() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
#######################
# Main script
#######################
log_message "Démarrage du backup"
# ...
🔝 Back to table of contents
6 - Practical exercises
Exercise 1: First script
# Create a script that displays:
# - The current date
# - The username
# - The current directory
# - The available disk space
Solution
#!/bin/bash
echo "Date: $(date)"
echo "Utilisateur: $USER"
echo "Répertoire: $(pwd)"
echo "Espace disque:"
df -h / | tail -1
Exercise 2: Script with arguments
# Create a script salut.sh that takes a name as an argument
# and displays "Bonjour, [nom] !"
# If no argument is given, display an error message
Solution
#!/bin/bash
if [ $# -eq 0 ]; then
echo "Erreur: Veuillez fournir un nom"
echo "Usage: $0 <nom>"
exit 1
fi
echo "Bonjour, $1 !"
Quiz
Q1. What is the recommended shebang for a portable script?
Answer
#!/usr/bin/env bash
Q2. How do you make a script executable?
Answer
chmod +x script.sh
Q3. What does the variable $# contain?
Answer
The number of arguments passed to the script
🔝 Back to table of contents
Key takeaways
- Shebang
#!/bin/bashspecifies the interpreter chmod +xmakes the script executable$1, $2...= arguments,$#= count,$@= all$?= return code of the last command- Always comment and document your scripts
- Use
"$@"with quotes to preserve spaces