Operations 25 min read

Essential Bash Scripts for Server Monitoring, Automation, and Security

This article presents a collection of practical Bash scripts that cover file consistency checks, scheduled log management, network traffic monitoring, numeric analysis, FTP downloads, user input handling, Nginx 502 detection, variable assignments, bulk file renaming, text processing, port scanning, word filtering, command menus, SSH automation with Expect, user creation, Apache monitoring, password rotation, iptables rate‑limiting, and IP validation, providing sysadmins with ready‑to‑use solutions for everyday Linux operations.

Open Source Linux
Open Source Linux
Open Source Linux
Essential Bash Scripts for Server Monitoring, Automation, and Security

1. Detect file consistency between two servers

#!/bin/bash
######################################
# Detect file consistency between two servers
#####################################
# Compare MD5 values of files in a directory on both servers

dir=/data/web
b_ip=192.168.88.10
# Generate MD5 list for server A
find $dir -type f | xargs md5sum > /tmp/md5_a.txt
# Generate MD5 list for server B via SSH
ssh $b_ip "find $dir -type f | xargs md5sum > /tmp/md5_b.txt"
scp $b_ip:/tmp/md5_b.txt /tmp
# Compare each file
for f in $(awk '{print $2}' /tmp/md5_a.txt); do
  if grep -qw "$f" /tmp/md5_b.txt; then
    md5_a=$(grep -w "$f" /tmp/md5_a.txt | awk '{print $1}')
    md5_b=$(grep -w "$f" /tmp/md5_b.txt | awk '{print $1}')
    if [ $md5_a != $md5_b ]; then
      echo "$f changed."
    fi
  else
    echo "$f deleted."
  fi
done

2. Hourly log clearing and file‑size recording

#!/bin/bash
#################################################################
# Every hour: at 00 or 12 clear file contents; otherwise log sizes
################################################################
logfile=/tmp/$(date +%H-%F).log
n=$(date +%H)
if [ $n -eq 00 ] || [ $n -eq 12 ]; then
  for i in $(find /data/log/ -type f); do
    true > $i
  done
else
  for i in $(find /data/log/ -type f); do
    du -sh $i >> $logfile
  done
fi

3. Network interface traffic logging

#!/bin/bash
#######################################################
# Log network interface traffic every minute
#######################################################
LANG=en
logfile=/tmp/$(date +%d).log
exec >> $logfile
date +"%F %H:%M"
sar -n DEV 1 59 | grep Average | grep ens33 | awk '{print $2,"\t","input:\t",$5*1000*8,"bps
",$2,"\t","output:\t",$6*1000*8,"bps"}'
echo "####################"
# Loop continues without sleep because sar runs 59 seconds

4. Count numbers per line and total in a document

#!/bin/bash
#########################################################
# Count numeric characters per line and total sum
#########################################################
n=$(wc -l a.txt | awk '{print $1}')
sum=0
for i in $(seq 1 $n); do
  line=$(sed -n "${i}p" a.txt)
  n_n=$(echo $line | sed 's/[^0-9]//g' | wc -L)
  sum=$((sum + n_n))
  echo "$n_n"
done
echo "sum:$sum"

5. Kill all scripts matching a pattern

#!/bin/bash
################################################################
# Kill processes matching a given name to reduce load
################################################################
ps aux | grep "指定进程名" | grep -v grep | awk '{print $2}' | xargs kill -9

6. Download a file from an FTP server

#!/bin/bash
if [ $# -ne 1 ]; then
  echo "Usage: $0 filename"
fi
dir=$(dirname $1)
file=$(basename $1)
ftp -n -v <<EOF
open 192.168.1.10
user admin password
binary
cd $dir
get "$file"
EOF

7. Read five numbers (0‑100) and report sum, min, max

#!/bin/bash
COUNT=1
SUM=0
MIN=0
MAX=100
while [ $COUNT -le 5 ]; do
  read -p "请输入1-10个整数:" INT
  if [[ ! $INT =~ ^[0-9]+$ ]]; then
    echo "输入必须是整数!"
    exit 1
  elif [[ $INT -gt 100 ]]; then
    echo "输入必须是100以内!"
    exit 1
  fi
  SUM=$((SUM+INT))
  [ $MIN -lt $INT ] && MIN=$INT
  [ $MAX -gt $INT ] && MAX=$INT
  let COUNT++
done
echo "SUM: $SUM"
echo "MIN: $MIN"
echo "MAX: $MAX"

8. Number guessing game

#!/bin/bash
# Generate a random number between 1 and 100
num=$((RANDOM%100+1))
while :; do
  read -p "计算机生成了一个 1‑100 的随机数,你猜: " cai
  if [ $cai -eq $num ]; then
    echo "恭喜,猜对了"
    exit
  elif [ $cai -gt $num ]; then
    echo "Oops,猜大了"
  else
    echo "Oops,猜小了"
  fi
done

9. Monitor Nginx access log for 502 errors and restart php‑fpm

#!/bin/bash
# Path to access log
log=/data/log/access.log
N=30   # threshold (10% of last 300 lines)
while :; do
  err=$(tail -n 300 $log | grep -c '502')
  if [ $err -ge $N ]; then
    /etc/init.d/php-fpm restart 2>/dev/null
    sleep 60   # prevent rapid restarts
  fi
  sleep 10
done

10. Assign command results to variables

# Example 1: simple loop
for i in $(echo "4 5 6"); do
  eval a$i=$i
done
echo $a4 $a5 $a6

# Example 2: split positional parameters like 192.168.1.1{1,2}
num=0
for i in $(eval echo $*); do
  let num+=1
  eval node${num}="$i"
done
echo $node1 $node2 $node3

# Example 3: array indexing
arr=(4 5 6)
INDEX1=$(echo ${arr[0]})
INDEX2=$(echo ${arr[1]})
INDEX3=$(echo ${arr[2]})

11. Batch rename files

# touch article_{1..3}.html
# Rename to bbs_*.html
for file in $(ls *html); do
  mv $file bbs_${file#*_}
done
# Alternative using find
for file in $(find . -maxdepth 1 -name "*html"); do
  mv $file bbs_${file#*_}
done
# Or using rename utility
# rename article bbs *.html

12. Delete lines containing letters in the first five lines and strip letters from lines 6‑10

# Sample file 2.txt
sed -n '1,5p' 2.txt | sed '/[a-zA-Z]/d'
sed -n '6,10p' 2.txt | sed 's/[a-zA-Z]//g'
sed -n '11,$p' 2.txt

13. Count total size of .html files in current directory

# Method 1
find . -name "*.html" -exec du -k {} \; | awk '{sum+=$1} END {print sum}'
# Method 2
sum=0
for size in $(ls -l *.html | awk '{print $5}'); do
  sum=$((sum+size))
done
echo $sum

14. Scan host ports

#!/bin/bash
HOST=$1
PORTS="22 25 80 8080"
for PORT in $PORTS; do
  if echo >/dev/null > /dev/tcp/$HOST/$PORT; then
    echo "$PORT open"
  else
    echo "$PORT close"
  fi
done

15. Print words with fewer than six letters from a sentence

# Example sentence
for s in Bash also interprets a number of multi-character options.; do
  n=$(echo $s | wc -c)
  if [ $n -lt 6 ]; then
    echo $s
  fi
done

16. Menu‑driven command executor

#!/bin/bash
echo "*cmd menu* 1-date 2-ls 3-who 4-pwd 0-exit "
while :; do
  read -p "please input number :" n
  [ -z "$n" ] && continue
  if ! [[ $n =~ ^[0-9]$ ]]; then exit 0; fi
  case $n in
    1) date ;;
    2) ls ;;
    3) who ;;
    4) pwd ;;
    0) break ;;
    *) echo "please input number is [1-4]" ;;
  esac
done

17. Expect script for password‑less SSH command execution

# Method 1: inline expect
#!/bin/bash
USER=root
PASS=123.com
IP=192.168.1.120
expect <<EOF
set timeout 30
spawn ssh $USER@$IP
expect {
  "(yes/no)" {send "yes\r"; exp_continue}
  "password:" {send "$PASS\r"}
}
expect "$USER@*" {send "$1\r"}
expect "$USER@*" {send "exit\r"}
expect eof
EOF

# Method 2: one‑liner
expect -c "
  spawn ssh $USER@$IP
  expect {\"(yes/no)\" {send \"yes\r\"; exp_continue} \"password:\" {send \"$PASS\r\"; exp_continue} \"$USER@*\" {send \"df -h\r exit\r\"; exp_continue}}
"

# Method 3: external script (login.exp) and loop over hosts
#!/bin/bash
HOST_INFO=user_info.txt
for ip in $(awk '{print $1}' $HOST_INFO); do
  user=$(awk -v I="$ip" 'I==$1{print $2}' $HOST_INFO)
  pass=$(awk -v I="$ip" 'I==$1{print $3}' $HOST_INFO)
  expect login.exp $ip $user $pass $1
done

18. Create 10 users with complex passwords and log them

#!/bin/bash
# Requires mkpasswd
for u in $(seq -w 0 09); do
  useradd user_$u
  p=$(mkpasswd -s 0 -l 10)
  echo $p | passwd --stdin user_$u
  echo "user_$u $p" >> /tmp/userpassword
done

19. Monitor httpd process count and restart Apache if needed

#!/bin/bash
check_service() {
  for i in $(seq 1 5); do
    /usr/local/apache2/bin/apachectl restart 2>/var/log/httpderr.log
    if [ $? -eq 0 ]; then break; else j=$((j+1)); fi
    [ $j -eq 5 ] && { mail.py; exit; }
  done
}
while :; do
  n=$(pgrep -l httpd | wc -l)
  if [ $n -gt 500 ]; then
    /usr/local/apache2/bin/apachectl restart
    if [ $? -ne 0 ]; then
      check_service
    else
      sleep 60
      n2=$(pgrep -l httpd | wc -l)
      [ $n2 -gt 500 ] && { mail.py; exit; }
    fi
  fi
  sleep 10
done

20. Batch change passwords for multiple servers

# old_pass.txt contains: IP User Password Port
OLD_INFO=old_pass.txt
NEW_INFO=new_pass.txt
for IP in $(awk '/^[^#]/{print $1}' $OLD_INFO); do
  USER=$(awk -v I=$IP 'I==$1{print $2}' $OLD_INFO)
  PASS=$(awk -v I=$IP 'I==$1{print $3}' $OLD_INFO)
  PORT=$(awk -v I=$IP 'I==$1{print $4}' $OLD_INFO)
  NEW_PASS=$(mkpasswd -l 8)
  echo "$IP $USER $NEW_PASS $PORT" >> $NEW_INFO
  expect -c "
    spawn ssh -p$PORT $USER@$IP
    set timeout 2
    expect {\"(yes/no)\" {send \"yes\r\"; exp_continue} \"password:\" {send \"$PASS\r\"; exp_continue} \"$USER@*\" {send \"echo '$NEW_PASS' |passwd --stdin $USER\r exit\r"; exp_continue}}
  "
done

21. iptables automatic blocking of abusive IPs

# Block IPs with >200 requests per minute (example for Nginx)
#!/bin/bash
DATE=$(date +%d/%b/%Y:%H:%M)
ABNORMAL_IP=$(tail -n5000 access.log | grep $DATE | awk '{a[$1]++} END {for(i in a) if(a[i]>100) print i}')
for IP in $ABNORMAL_IP; do
  if [ $(iptables -vnL | grep -c "$IP") -eq 0 ]; then
    iptables -I INPUT -s $IP -j DROP
  fi
done

# Block IPs with >10 failed SSH attempts per minute
#!/bin/bash
DATE=$(date +"%a %b %e %H:%M")
ABNORMAL_IP=$(lastb | grep "$DATE" | awk '{a[$3]++} END {for(i in a) if(a[i]>10) print i}')
for IP in $ABNORMAL_IP; do
  if [ $(iptables -vnL | grep -c "$IP") -eq 0 ]; then
    iptables -A INPUT -s $IP -j DROP
  fi
done

22. Dynamic IP banning based on web log traffic

#!/bin/bash
logfile=/data/log/access.log
d1=$(date -d "-1 minute" +%H%M)
d2=$(date +%M)
ipt=/sbin/iptables
ips=/tmp/ips.txt
block() {
  grep "$d1:" $logfile | awk '{print $1}' | sort -n | uniq -c | sort -n > $ips
  for i in $(awk '$1>100 {print $2}' $ips); do
    $ipt -I INPUT -p tcp --dport 80 -s $i -j REJECT
    echo "$(date +%F-%T) $i" >> /tmp/badip.log
done
}
unblock() {
  for a in $($ipt -nvL INPUT --line-numbers | grep '0.0.0.0/0' | awk '$2<10 {print $1}' | sort -nr); do
    $ipt -D INPUT $a
done
  $ipt -Z
}
if [ $d2 -eq 00 ] || [ $d2 -eq 30 ]; then
  unblock
  block
else
  block
fi

23. Validate user‑entered IP address

#!/bin/bash
function check_ip(){
  IP=$1
  if echo $IP | grep -E "^[0-9]{1,3}(\.[0-9]{1,3}){3}$" >/dev/null; then
    VALID=$(echo $IP | awk -F. '$1<=255 && $2<=255 && $3<=255 && $4<=255 {print "yes"}')
    if [ "$VALID" == "yes" ]; then
      echo "$IP available."
    else
      echo "$IP not available!"
    fi
  else
    echo "Format error!"
  fi
}
while true; do
  read -p "Please enter IP: " IP
  check_ip $IP && break
done
Illustrative diagram
Illustrative diagram
monitoringLinuxsecuritybashshell scriptingserver automation
Open Source Linux
Written by

Open Source Linux

Focused on sharing Linux/Unix content, covering fundamentals, system development, network programming, automation/operations, cloud computing, and related professional knowledge.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.