Comprehensive Guide to Loop Structures in Shell Scripting
For Loops
The for loop iterates over a list of values, executing a block of commands for each item.
Syntax:
for variable in item1 item2 ... itemN
do
command_sequence
doneExample 1: Iterating through a Numeric Range
To display numbers from 1 to 10:
#!/bin/bash
for num in {1..10}
do
echo "Current number: $num"
doneExample 2: Batch User Creation
This script reads usernames from a file and creates accounts with a default password.
#!/bin/bash
USER_LIST="/root/users.txt"
DEFAULT_PASS="Password123"
for username in $(cat $USER_LIST)
do
useradd "$username"
echo "$DEFAULT_PASS" | passwd --stdin "$username" &> /dev/null
done
echo "User creation process completed."Example 3: Network Connectivity Checker
Read IP addresses from a file and log their status based on ping results.
#!/bin/bash
TARGET_FILE="/root/ip_list.txt"
RESULT_FILE="/root/network_status.log"
for ip_addr in $(cat $TARGET_FILE)
do
# Send 2 packets, wait 1 second between pings, 2-second deadline
if ping -c 2 -i 1 -W 2 "$ip_addr" &> /dev/null; then
echo "$ip_addr: Online" >> "$RESULT_FILE"
else
echo "$ip_addr: Offline" >> "$RESULT_FILE"
fi
doneExample 4: Sequential IP Scanning
Check connectivity for a specific range of hosts (e.g., 192.168.10.10 through 60).
#!/bin/bash
BASE_IP="192.168.10"
for suffix in 10 20 30 40 50 60
do
TARGET="$BASE_IP.$suffix"
if ping -c 1 -W 1 "$TARGET" &> /dev/null; then
echo "$TARGET is reachable."
else
echo "$TARGET is unreachable."
fi
doneExample 5: Odd and Even Detection
Using a C-style for loop to determine parity.
#!/bin/bash
for (( i=1; i<=10; i++ ))
do
remainder=$(( i % 2 ))
if [ $remainder -ne 0 ]; then
echo "$i is an odd number."
else
echo "$i is an even number."
fi
doneExample 6: Parallel Subnet Scan
Scanning a /24 subnet using background processes for speed.
#!/bin/bash
SUBNET="192.168.80"
OUTPUT_FILE="active_hosts.txt"
for host_suffix in {1..254}
do
(
IP="$SUBNET.$host_suffix"
if ping -c 1 -W 1 "$IP" &> /dev/null; then
echo "$IP" >> "$OUTPUT_FILE"
fi
) &
done
wait
cat "$OUTPUT_FILE"Example 7: Calculating a Cumulative Sum
Summing integers from 1 to 10.
#!/bin/bash
total_sum=0
for (( i=1; i<=10; i++ ))
do
total_sum=$(( total_sum + i ))
done
echo "The sum of 1 to 10 is: $total_sum"Example 8: Searching Executables in PATH
Iterate through the PATH environment variable to find files starting with a specific prefix.
#!/bin/bash
OLD_IFS=$IFS
IFS=':'
for directory in $PATH
do
# Silently find files starting with 'py'
find "$directory" -name "py*" -print 2> /dev/null
done
IFS=$OLD_IFSExample 9: Generating Fibonacci Sequence
Printing the first 10 numbers of the Fibonacci sequence (1, 1, 2, 3, 5...).
#!/bin/bash
prev=1
curr=1
for (( i=0; i<10; i++ ))
do
echo "$prev"
next=$(( prev + curr ))
prev=$curr
curr=$next
doneExample 10: Random Password Generator
Generating an 8-character random password using alphanumeric characters.
#!/bin/bash
CHAR_SET="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
PASS_LEN=8
PASSWORD=""
for (( i=0; i<PASS_LEN; i++ ))
do
# Get random index based on string length
index=$(( RANDOM % ${#CHAR_SET} ))
# Extract character at index
char="${CHAR_SET:$index:1}"
PASSWORD+="$char"
done
echo "Generated Password: $PASSWORD"Example 11: Intelligent User Management
Check if users exist in /etc/passwd. If they exist, verify password status; otherwise, create them.
#!/bin/bash
INPUT_FILE="/root/users.txt"
for user in $(cat "$INPUT_FILE")
do
# Check if user exists
if id "$user" &> /dev/null; then
echo "User '$user' already exists."
# Check if password is set (checking shadow file)
pass_status=$(grep "^$user:" /etc/shadow | cut -d: -f2)
if [ -z "$pass_status" ] || [ "$pass_status" == "!" ] || [ "$pass_status" == "!!" ]; then
echo "User '$user' has no password."
read -p "Set password for $user: " -s pass1
echo
read -p "Confirm password: " -s pass2
echo
if [ "$pass1" == "$pass2" ]; then
echo "$pass1" | passwd --stdin "$user" &> /dev/null
echo "Password updated."
else
echo "Passwords do not match."
fi
fi
else
echo "User '$user' does not exist. Creating..."
read -p "Enter password for new user: " -s new_pass
echo
useradd "$user"
echo "$new_pass" | passwd --stdin "$user" &> /dev/null
echo "User created."
fi
doneWhile Loops
The while loop executes commands as long as the control condition remains true.
Syntax:
while [ condition ]
do
command_sequence
doneExample 1: Summing User Input
Calculate the sum of numbers from 1 to a user-provided value (N).
#!/bin/bash
read -p "Enter an integer (1-100): " limit
counter=1
sum=0
if [[ $limit -ge 1 && $limit -le 100 ]]; then
while [ $counter -le $limit ]
do
sum=$(( sum + counter ))
(( counter++ ))
done
echo "Sum from 1 to $limit is: $sum"
else
echo "Input out of range."
fiExample 2: Separating Odd and Even Sums
Calculate the sum of all odd and even numbers between 1 and 100.
#!/bin/bash
i=1
odd_total=0
even_total=0
while [ $i -le 100 ]
do
if [ $(( i % 2 )) -eq 0 ]; then
even_total=$(( even_total + i ))
else
odd_total=$(( odd_total + i ))
fi
(( i++ ))
done
echo "Odd Sum: $odd_total"
echo "Even Sum: $even_total"Example 3: Host Discovery Loop
Check IP addresses ending in 100 through 104.
#!/bin/bash
host_id=100
LOG_FILE="/root/active_hosts.log"
while [ $host_id -le 104 ]
do
IP_ADDR="192.168.10.$host_id"
ping -c 1 -W 1 "$IP_ADDR" &> /dev/null
if [ $? -eq 0 ]; then
echo "$IP_ADDR is up" >> "$LOG_FILE"
fi
(( host_id++ ))
done
echo "Scan complete. Results in $LOG_FILE."Example 4: Login Attempt Limiter
Allow a user 3 attempts to enter the correct password.
#!/bin/bash
CORRECT_PASS="secret123"
attempts=0
max_attempts=3
while [ $attempts -lt $max_attempts ]
do
read -p "Enter password: " user_input
if [ "$user_input" == "$CORRECT_PASS" ]; then
echo "Access granted."
exit 0
else
echo "Incorrect password."
fi
(( attempts++ ))
done
echo "Maximum attempts reached. Exiting."Example 5: Decimal to Binary Conversion
Convert a decimal number (0-255) to an 8-bit binary string.
#!/bin/bash
read -p "Enter a number (0-255): " dec_num
binary_str=""
for weight in 128 64 32 16 8 4 2 1
do
if [ $dec_num -ge $weight ]; then
binary_str+="1"
dec_num=$(( dec_num - weight ))
else
binary_str+="0"
fi
done
echo "Binary: $binary_str"Example 6: Splitting Files by Line Count
Split a large file into smaller files containing 50 lines each.
#!/bin/bash
SOURCE_FILE="/root/large_log.txt"
line_count=0
file_part=1
# Ensure output directory exists
mkdir -p "/root/split_files/"
while IFS= read -r line
do
echo "$line" >> "/root/split_files/part_${file_part}.txt"
(( line_count++ ))
if [ $(( line_count % 50 )) -eq 0 ]; then
(( file_part++ ))
fi
done < "$SOURCE_FILE"Until Loops
The until loop operates conversely to the while loop; it executes until the condition becomes true.
Syntax:
until [ condition ]
do
command_sequence
doneExample 1: Countdown Execution
Print numbers starting from 1 until the number exceeds 10.
#!/bin/bash
val=1
until [ $val -gt 10 ]
do
echo "Number: $val"
(( val++ ))
done