#Bash Scripting
Bash is the default shell on most Linux systems and essential for DevOps automation.
#📋 Table of Contents
#Script Basics
#Creating a Script
bash
1#!/bin/bash
2# This is a comment
3# script-name.sh - Description of script
4
5echo "Hello, DevOps!"#Running Scripts
bash
1# Make executable
2chmod +x script.sh
3
4# Run
5./script.sh
6
7# Or with bash
8bash script.sh#Shebang Options
bash
#!/bin/bash # Standard bash
#!/usr/bin/env bash # Portable (finds bash in PATH)
#!/bin/sh # POSIX shell (more portable)#Variables
#Basic Variables
bash
1# Assignment (no spaces around =)
2name="DevOps"
3count=42
4
5# Using variables
6echo "Hello, $name"
7echo "Count: ${count}"
8
9# Command substitution
10current_date=$(date +%Y-%m-%d)
11hostname=$(hostname)
12
13# Read-only
14readonly PI=3.14159
15
16# Arrays
17servers=("web-01" "web-02" "web-03")
18echo "First: ${servers[0]}"
19echo "All: ${servers[@]}"
20echo "Count: ${#servers[@]}"#Special Variables
bash
1$0 # Script name
2$1, $2, $3 # Positional arguments
3$# # Number of arguments
4$@ # All arguments as separate words
5$* # All arguments as single string
6$? # Exit status of last command
7$$ # Current process ID
8$! # PID of last background process#Environment Variables
bash
1# Export for child processes
2export MY_VAR="value"
3
4# Common variables
5echo "User: $USER"
6echo "Home: $HOME"
7echo "Path: $PATH"
8echo "Shell: $SHELL"#Control Flow
#If Statements
bash
1# Basic if
2if [ "$name" = "DevOps" ]; then
3 echo "Match!"
4fi
5
6# If-else
7if [ -f "/etc/nginx/nginx.conf" ]; then
8 echo "Nginx is installed"
9else
10 echo "Nginx not found"
11fi
12
13# If-elif-else
14if [ "$status" = "healthy" ]; then
15 echo "All good"
16elif [ "$status" = "warning" ]; then
17 echo "Check logs"
18else
19 echo "Critical!"
20fi
21
22# Using [[ ]] for extended tests (bash-specific)
23if [[ "$name" == Dev* ]]; then
24 echo "Starts with Dev"
25fi#Test Operators
bash
1# String comparisons
2[ "$a" = "$b" ] # Equal
3[ "$a" != "$b" ] # Not equal
4[ -z "$a" ] # Zero length
5[ -n "$a" ] # Non-zero length
6
7# Numeric comparisons
8[ "$a" -eq "$b" ] # Equal
9[ "$a" -ne "$b" ] # Not equal
10[ "$a" -lt "$b" ] # Less than
11[ "$a" -gt "$b" ] # Greater than
12[ "$a" -le "$b" ] # Less or equal
13[ "$a" -ge "$b" ] # Greater or equal
14
15# File tests
16[ -f "$file" ] # Is file
17[ -d "$dir" ] # Is directory
18[ -e "$path" ] # Exists
19[ -r "$file" ] # Readable
20[ -w "$file" ] # Writable
21[ -x "$file" ] # Executable
22[ -s "$file" ] # Non-zero size
23
24# Logical operators
25[ cond1 ] && [ cond2 ] # AND
26[ cond1 ] || [ cond2 ] # OR
27[ ! cond ] # NOT#Loops
bash
1# For loop - list
2for server in web-01 web-02 web-03; do
3 echo "Processing $server"
4done
5
6# For loop - array
7servers=("web-01" "web-02" "web-03")
8for server in "${servers[@]}"; do
9 echo "Processing $server"
10done
11
12# For loop - range
13for i in {1..10}; do
14 echo "Number: $i"
15done
16
17# For loop - C-style
18for ((i=0; i<10; i++)); do
19 echo "Index: $i"
20done
21
22# For loop - files
23for file in /etc/*.conf; do
24 echo "Config: $file"
25done
26
27# While loop
28count=0
29while [ $count -lt 5 ]; do
30 echo "Count: $count"
31 ((count++))
32done
33
34# Read file line by line
35while IFS= read -r line; do
36 echo "Line: $line"
37done < file.txt
38
39# Infinite loop with break
40while true; do
41 if [ -f "/tmp/stop" ]; then
42 break
43 fi
44 sleep 1
45done#Case Statement
bash
1case "$action" in
2 start)
3 echo "Starting..."
4 ;;
5 stop)
6 echo "Stopping..."
7 ;;
8 restart)
9 echo "Restarting..."
10 ;;
11 *)
12 echo "Usage: $0 {start|stop|restart}"
13 exit 1
14 ;;
15esac#Functions
bash
1# Simple function
2greet() {
3 echo "Hello, $1!"
4}
5
6greet "DevOps"
7
8# Function with return value
9is_healthy() {
10 local host=$1
11 ping -c 1 "$host" &>/dev/null
12 return $?
13}
14
15if is_healthy "google.com"; then
16 echo "Host is reachable"
17fi
18
19# Function with output
20get_ip() {
21 hostname -I | awk '{print $1}'
22}
23
24my_ip=$(get_ip)
25echo "My IP: $my_ip"
26
27# Local variables
28calculate() {
29 local result=$(( $1 + $2 ))
30 echo $result
31}
32
33sum=$(calculate 5 3)#Input and Output
#Reading Input
bash
1# Read from user
2read -p "Enter name: " name
3echo "Hello, $name"
4
5# Read with default
6read -p "Port [8080]: " port
7port=${port:-8080}
8
9# Read password (hidden)
10read -sp "Password: " password
11echo
12
13# Read with timeout
14read -t 5 -p "Quick! " answer#Output Redirection
bash
1# Redirect stdout
2echo "log message" > file.txt # Overwrite
3echo "log message" >> file.txt # Append
4
5# Redirect stderr
6command 2> errors.txt
7
8# Redirect both
9command > output.txt 2>&1
10command &> output.txt # Bash shorthand
11
12# Discard output
13command > /dev/null 2>&1
14
15# Pipe to another command
16cat file.txt | grep "error" | wc -l#Here Documents
bash
1# Multi-line input
2cat << EOF
3This is a multi-line
4text block that will be
5printed as-is.
6EOF
7
8# Write to file
9cat << EOF > /tmp/config.yaml
10server:
11 port: 8080
12 host: localhost
13EOF#Error Handling
bash
1#!/bin/bash
2set -e # Exit on error
3set -u # Error on undefined variable
4set -o pipefail # Pipe fails if any command fails
5
6# Combined (recommended)
7set -euo pipefail
8
9# Trap errors
10trap 'echo "Error on line $LINENO"; exit 1' ERR
11
12# Trap cleanup
13cleanup() {
14 echo "Cleaning up..."
15 rm -f /tmp/tempfile
16}
17trap cleanup EXIT
18
19# Check command success
20if ! command -v docker &>/dev/null; then
21 echo "Docker is not installed"
22 exit 1
23fi
24
25# Validate arguments
26if [ $# -lt 1 ]; then
27 echo "Usage: $0 <argument>"
28 exit 1
29fi#Best Practices
#Script Template
bash
1#!/bin/bash
2set -euo pipefail
3
4# =============================================================================
5# Script: deploy.sh
6# Description: Deploy application to servers
7# Usage: ./deploy.sh <environment> [version]
8# =============================================================================
9
10# Constants
11readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12readonly LOG_FILE="/var/log/deploy.log"
13
14# Functions
15log() {
16 echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"
17}
18
19error() {
20 log "ERROR: $*" >&2
21 exit 1
22}
23
24usage() {
25 echo "Usage: $0 <environment> [version]"
26 echo " environment: staging|production"
27 echo " version: deployment version (default: latest)"
28 exit 1
29}
30
31cleanup() {
32 log "Cleaning up..."
33}
34
35# Main
36main() {
37 trap cleanup EXIT
38
39 # Validate arguments
40 [[ $# -lt 1 ]] && usage
41
42 local environment=$1
43 local version=${2:-latest}
44
45 log "Deploying version $version to $environment"
46
47 # Your deployment logic here
48
49 log "Deployment complete!"
50}
51
52main "$@"#Summary
| Concept | Example |
|---|---|
| Variables | name="value" |
| Arguments | $1, $2, $@ |
| Condition | if [ -f file ]; then |
| Loop | for item in list; do |
| Function | func() { ... } |
| Error handling | set -euo pipefail |
[!TIP] Pro Tip: Use ShellCheck to validate your scripts for common errors!