Shell
Scripting Language
Shell
Overview
Shell is a scripting language for command-line operations and automation scripts on Unix-like operating systems. It plays important roles in various scenarios including system administration, file operations, process control, and CI/CD pipelines. There are several types including Bash, Zsh, and Fish.
Details
The most common Bash (Bourne Again Shell) was developed in 1989 as part of the GNU project. It is widely adopted as the standard shell for Unix-like systems and is used on Linux, macOS, WSL, and other platforms.
Shell scripts can automate complex tasks using combinations of commands, conditional statements, loops, and functions. With the spread of DevOps, its importance has increased in Infrastructure as Code, CI/CD, and container management.
Code Examples
Hello World
#!/bin/bash
echo "Hello, World!"
Variables and Basic Operations
#!/bin/bash
# Variable definition
name="John"
age=25
current_date=$(date)
# Variable usage
echo "Name: $name"
echo "Age: ${age} years old"
echo "Current time: $current_date"
# Numeric calculation
x=10
y=5
sum=$((x + y))
echo "$x + $y = $sum"
# String manipulation
text="Hello World"
echo "Length: ${#text}"
echo "Uppercase: ${text^^}"
echo "Lowercase: ${text,,}"
Command Line Arguments and Conditionals
#!/bin/bash
# Check command line arguments
if [ $# -eq 0 ]; then
echo "Usage: $0 <filename>"
exit 1
fi
filename=$1
# Check file existence
if [ -f "$filename" ]; then
echo "File '$filename' found"
# Check file attributes
if [ -r "$filename" ]; then
echo "Readable"
fi
if [ -w "$filename" ]; then
echo "Writable"
fi
if [ -x "$filename" ]; then
echo "Executable"
fi
# Display file information
echo "File size: $(stat -f%z "$filename" 2>/dev/null || stat -c%s "$filename" 2>/dev/null) bytes"
echo "Last modified: $(stat -f%Sm "$filename" 2>/dev/null || stat -c%y "$filename" 2>/dev/null)"
elif [ -d "$filename" ]; then
echo "'$filename' is a directory"
echo "Number of files: $(ls -1 "$filename" | wc -l)"
else
echo "File '$filename' not found"
exit 1
fi
Loops and Arrays
#!/bin/bash
# Array definition
fruits=("apple" "banana" "orange" "grape")
# Display array (for loop)
echo "Fruit list:"
for fruit in "${fruits[@]}"; do
echo "- $fruit"
done
# Loop with index
echo -e "\nNumbered list:"
for i in "${!fruits[@]}"; do
echo "$((i+1)). ${fruits[i]}"
done
# While loop example
echo -e "\nNumbers 1 to 5:"
counter=1
while [ $counter -le 5 ]; do
echo "Number: $counter"
((counter++))
done
# File processing loop
echo -e "\nText files in current directory:"
for file in *.txt; do
if [ -f "$file" ]; then
echo "Text file: $file"
fi
done
Functions and Argument Processing
#!/bin/bash
# Simple function
greet() {
local name=$1
local time=$2
echo "${time}, ${name}!"
}
# File backup function
backup_file() {
local source_file=$1
local backup_dir=$2
# Argument check
if [ $# -ne 2 ]; then
echo "Usage: backup_file <source_file> <backup_directory>"
return 1
fi
# Check source file existence
if [ ! -f "$source_file" ]; then
echo "Error: File '$source_file' not found"
return 1
fi
# Create backup directory
mkdir -p "$backup_dir"
# Generate backup filename
local filename=$(basename "$source_file")
local timestamp=$(date +"%Y%m%d_%H%M%S")
local backup_file="${backup_dir}/${filename}.backup.${timestamp}"
# Copy file
if cp "$source_file" "$backup_file"; then
echo "Backup completed: $backup_file"
return 0
else
echo "Error: Backup failed"
return 1
fi
}
# Function usage
greet "John" "Good morning"
greet "Jane" "Good evening"
# Test backup function
echo "sample.txt" > sample.txt
backup_file "sample.txt" "./backup"
System Administration Script
#!/bin/bash
# System information collection script
collect_system_info() {
echo "=== System Information Report ==="
echo "Generated: $(date)"
echo ""
# OS information
echo "=== OS Information ==="
if command -v lsb_release >/dev/null 2>&1; then
lsb_release -a
elif [ -f /etc/os-release ]; then
cat /etc/os-release
else
uname -a
fi
echo ""
# CPU information
echo "=== CPU Information ==="
if [ -f /proc/cpuinfo ]; then
grep "model name" /proc/cpuinfo | head -1
echo "CPU count: $(nproc)"
fi
echo ""
# Memory information
echo "=== Memory Information ==="
if command -v free >/dev/null 2>&1; then
free -h
fi
echo ""
# Disk usage
echo "=== Disk Usage ==="
df -h
echo ""
# Process information (top 5 by CPU usage)
echo "=== Top CPU Usage Processes ==="
ps aux --sort=-%cpu | head -6
echo ""
# Network connections
echo "=== Network Connections ==="
if command -v ss >/dev/null 2>&1; then
ss -tuln
elif command -v netstat >/dev/null 2>&1; then
netstat -tuln
fi
}
# Log rotation function
rotate_logs() {
local log_dir=$1
local days_to_keep=$2
if [ $# -ne 2 ]; then
echo "Usage: rotate_logs <log_directory> <days_to_keep>"
return 1
fi
echo "Starting log rotation: $log_dir"
# Delete old log files
find "$log_dir" -name "*.log" -type f -mtime +$days_to_keep -delete
# Delete compressed log files too
find "$log_dir" -name "*.log.gz" -type f -mtime +$days_to_keep -delete
echo "Log rotation completed"
}
# Usage examples
collect_system_info > system_report_$(date +%Y%m%d).txt
rotate_logs "/var/log/myapp" 30
Error Handling and Debugging
#!/bin/bash
# Exit on error
set -e
# Exit on undefined variable usage
set -u
# Exit on first failure in pipeline
set -o pipefail
# Debug mode (display executed commands)
# set -x
# Error handling function
error_exit() {
echo "Error: $1" >&2
exit 1
}
# Cleanup function
cleanup() {
echo "Running cleanup..."
# Delete temporary files etc.
rm -f /tmp/script_temp_*
}
# Signal handling (cleanup on script exit)
trap cleanup EXIT
trap 'error_exit "Script interrupted"' INT TERM
# File processing example
process_file() {
local input_file=$1
local output_file=$2
# Check input file
[ -f "$input_file" ] || error_exit "Input file not found: $input_file"
# Create output directory
local output_dir=$(dirname "$output_file")
mkdir -p "$output_dir" || error_exit "Failed to create output directory: $output_dir"
# Execute processing
if ! grep -v "^#" "$input_file" > "$output_file"; then
error_exit "File processing failed"
fi
echo "Processing completed: $output_file"
}
# Usage example
echo "Script started"
process_file "/etc/hosts" "/tmp/hosts_filtered.txt"
echo "Script completed successfully"
Advantages and Disadvantages
Advantages
- System Integration: Direct integration with OS commands
- Automation: Efficient automation of repetitive tasks
- Lightweight: Available immediately without additional installation
- DevOps Support: Standard tool for CI/CD and infrastructure management
- Text Processing: Powerful text processing with pipes and redirection
- Rich Commands: Wide range of processing possible with Unix tools
Disadvantages
- Readability: Complex scripts are difficult to understand
- Error Handling: Default error handling is insufficient
- Portability: Differences between OS and shells
- Debugging: Limited debugging tools
- Large-scale Development: Unsuitable for large application development
Key Links
- GNU Bash Manual
- ShellCheck - Shell Script Analysis Tool
- Advanced Bash-Scripting Guide
- Zsh Official Site
Ranking Information
- Overall Ranking: 9th
- GitHub Usage: 5th
- RedMonk Language Ranking: 14th
- IEEE Spectrum: 14th
- JetBrains Developer Survey: 7th
Shell is an essential scripting language for system administration and DevOps, playing important roles in automation and system integration.