A Beginner's Guide to Shell Scripting: Key Concepts, Examples, and Best Practices
Shell scripting is a powerful tool for automating tasks in a Linux environment. It enables developers and system administrators to execute a series of commands efficiently, saving time and reducing human error. In this blog, we’ll cover the essentials of shell scripting, provide examples, and highlight its practical applications.
What is a Shell and Shell Scripting?
Shell
A shell is a Command Line Interface (CLI) that interprets and executes Linux commands. For example:
ls -l
: Displays detailed information about files and directories.df -h
: Displays disk usage in a human-readable format.top
: Shows real-time system performance, including processes and memory usage.
Shell Script
A shell script is a file containing a sequence of shell commands, variables, functions, and control structures (e.g., loops, conditions). These scripts automate repetitive tasks.
Why Use Shell Scripting?
Automation: Streamlines manual tasks such as server setup, software installation, deployment, and log management.
Efficiency: Reduces execution time and human error.
Reusability: Write once and use across different environments.
Flexibility: Manage files, interact with databases, and handle system-level operations.
Getting Started with Shell Scripting
Shebang
Every shell script begins with a shebang:#!/bin/bash
This specifies the interpreter (e.g., bash) to execute the script.
Executing a Shell Script
sh <script_name>
bash <script_name>
./<script_name>
(Ensure the script has executable permissions:chmod +x <script_name>
)
Core Concepts
Variables
Variables store values that can be reused throughout the script.
Example:
#!/bin/bash
NAME="John"
echo "Hello, $NAME!"
Arrays
Store multiple values in a single variable.
Example:
MOVIES=("RRR" "DjTillu" "Murari")
echo "First Movie: ${MOVIES[0]}"
echo "All Movies: ${MOVIES[@]}"
Conditions
Control the flow based on conditions.
Example:
#!/bin/bash
NUMBER=$1
if [ $NUMBER -gt 10 ]; then
echo "Number is greater than 10"
else
echo "Number is less than or equal to 10"
fi
Loops
Repeat tasks efficiently.
Example:
for i in {1..5}; do
echo "Iteration: $i"
done
Real-Time Useful Commands
Here are some real-world shell commands that are useful for daily operations:
File Management
cp -r source_dir/ target_dir/
: Copy directories recursively.rm -rf /tmp/*
: Delete all files and directories in/tmp
.
Process and Memory Monitoring
ps aux
: Show all running processes.top | grep java
: Monitor resource usage for Java processes.
Networking
ping
google.com
: Check network connectivity.netstat -tuln
: Display active network connections.
Disk Space Management
df -h /
: Display available disk space in the root directory.du -sh /path/to/dir
: Show the size of a specific directory.
Log Management
tail -f /var/log/syslog
: Monitor a log file in real-time.find /var/log -name "*.log" -type f -size +10M
: Find log files larger than 10 MB.
User Management
whoami
: Show the current user.sudo useradd new_user
: Add a new user.
Practical Applications
Automating Server Setup
Example script for configuring a Node.js server:
#!/bin/bash
# Update and install dependencies
sudo apt update
sudo apt install -y nodejs npm
# Setup application
mkdir /var/myapp
cd /var/myapp
wget https://example.com/app.zip
unzip app.zip
npm install
# Start application as a service
cat <<EOF > /etc/systemd/system/myapp.service
[Unit]
Description=My Node.js App
[Service]
ExecStart=/usr/bin/node /var/myapp/app.js
Restart=always
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp
Deployment Automation
Automate the deployment of a new application version:
#!/bin/bash
APP_DIR="/var/myapp"
NEW_VERSION="https://example.com/new_version.zip"
# Stop the server
sudo systemctl stop myapp
# Update code
rm -rf $APP_DIR/*
wget $NEW_VERSION -O app.zip
unzip app.zip -d $APP_DIR
npm install
# Restart the server
sudo systemctl start myapp
Old Log Deletion Use Case
Managing logs is a common use case in real-world systems. Here’s a script to delete old logs:
#!/bin/bash
LOG_DIR="/var/log/myapp" # Specify the log directory
RETENTION_DAYS=14 # Retain logs for 14 days
# Find and delete logs older than the retention period
find $LOG_DIR -name "*.log" -type f -mtime +$RETENTION_DAYS -exec rm {} \;
echo "Old logs deleted successfully from $LOG_DIR."
This script ensures your system remains clean and avoids storage issues due to accumulated logs.
Advanced Concepts
Error Handling
Errors are inevitable in shell scripts. Use exit codes to handle them.
Example:
#!/bin/bash
set -e # Exit immediately if a command fails
if ! mkdir /var/test; then
echo "Failed to create directory."
exit 1
fi
echo "Directory created successfully."
Functions
Reuse blocks of code by defining functions.
Example:
#!/bin/bash
greet() {
echo "Hello, $1!"
}
greet "Alice"
Log Management
Rotate and delete old log files:
#!/bin/bash
LOG_DIR="/var/log/myapp"
find $LOG_DIR -name "*.log" -type f -mtime +14 -exec rm {} \;
echo "Old logs deleted."
Scheduling Tasks
Use crontab
for scheduling.
Example:
# Run a script daily at midnight
0 0 * * * /path/to/script.sh
Best Practices
Use Version Control: Store scripts in GitHub/GitLab for collaboration and backup.
Write Modular Scripts: Break large scripts into smaller, reusable functions.
Add Comments: Explain complex sections of code.
Handle Errors Gracefully: Use
set -e
and proper error handling.Test Thoroughly: Validate scripts in a safe environment before production.