Operations 25 min read
Essential Bash Scripts for Linux Operations: Sync, Monitoring, and Automation
A comprehensive collection of Bash scripts demonstrates how to verify file consistency across servers, automate log rotation, monitor network traffic, manage users and passwords, detect service failures, and enforce security policies, providing practical solutions for everyday Linux system administration tasks.
Efficient Ops
Efficient Ops
1. Detect file consistency between two servers
<code>#!/bin/bash
######################################
# Detect file consistency between two servers
#####################################
# Compare md5 values of files in a directory on two servers
dir=/data/web
b_ip=192.168.88.10
# Generate md5 list for local server
find $dir -type f | xargs md5sum > /tmp/md5_a.txt
# Generate md5 list for remote server
ssh $b_ip "find $dir -type f | xargs md5sum > /tmp/md5_b.txt"
scp $b_ip:/tmp/md5_b.txt /tmp
# Compare files
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</code>2. Periodically clear file contents and log file sizes
<code>#!/bin/bash
#################################################################
# Run hourly; at 00:00 or 12:00 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</code>3. Monitor network interface traffic and log
<code>#!/bin/bash
#######################################################
# Record network traffic every minute in bps
#######################################################
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","\n",$2,"\t","output:\t",$6*1000*8,"bps"}'
echo "####################"
# Loop continues without sleep because sar runs 59 seconds
while :; do :; done</code>4. Count numbers per line and total numbers in a document
<code>#!/bin/bash
#########################################################
# Count numeric characters per line and total in a file
#########################################################
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"</code>5. Kill all scripts
<code>#!/bin/bash
################################################################
# Kill processes matching a given name to reduce load
################################################################
ps aux | grep "指定进程名" | grep -v grep | awk '{print $2}' | xargs kill -9</code>6. Download a file from an FTP server
<code>#!/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</code>7. Input five numbers (0‑100) and compute sum, min, max
<code>#!/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"</code>8. Number guessing game
<code>#!/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</code>9. Monitor Nginx access log for 502 errors and restart php‑fpm
<code>#!/bin/bash
# Scenario: LNMP environment, 502 errors disappear after php‑fpm restart
log=/data/log/access.log
N=30 # threshold: 30 occurrences in last 300 lines (~10% of 300)
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 restart loops
fi
sleep 10
done</code>10. Delete lines with letters in first five lines and strip letters from lines 6‑10
<code># Delete lines 1‑5 that contain letters, then remove all letters from lines 6‑10
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</code>11. Calculate total size of .html files in current directory
<code># Method 1 (du)
find . -name "*.html" -exec du -k {} \; | awk '{sum+=$1} END {print sum}'
# Method 2 (ls)
sum=0
for size in $(ls -l *.html | awk '{print $5}'); do
sum=$((sum+size))
done
echo $sum</code>12. Scan host ports
<code>#!/bin/bash
HOST=$1
PORTS="22 25 80 8080"
for PORT in $PORTS; do
if echo >/dev/tcp/$HOST/$PORT 2>/dev/null; then
echo "$PORT open"
else
echo "$PORT close"
fi
done</code>13. Print words with fewer than six letters from a sentence
<code># 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</code>14. Menu‑driven command execution based on numeric input
<code>#!/bin/bash
echo "*cmd menu* 1-date 2-ls 3-who 4-pwd 0-exit"
while :; do
read -p "please input number :" n
if [ -z "$n" ]; then continue; fi
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</code>15. Expect script for SSH non‑interactive command execution
<code># login.exp (Expect script)
#!/usr/bin/expect
set ip [lindex $argv 0]
set user [lindex $argv 1]
set passwd [lindex $argv 2]
set cmd [lindex $argv 3]
if { $argc != 4 } { puts "Usage: expect login.exp ip user passwd cmd"; exit 1 }
set timeout 30
spawn ssh $user@$ip
expect {
"(yes/no)" { send "yes\r"; exp_continue }
"password:" { send "$passwd\r" }
}
expect "$user@*" { send "$cmd\r" }
expect "$user@*" { send "exit\r" }
expect eof</code>16. Create 10 users with random passwords and log them
<code>#!/bin/bash
for u in $(seq -w 0 09); do
useradd user_$u
p=$(mkpasswd -s 0 -l 10)
echo $p | passwd --stdin user_$u
echo "$p" | passwd user_$u
echo "user_$u $p" >> /tmp/userpassword
done</code>17. Monitor httpd process count and restart Apache if needed
<code>#!/bin/bash
check_service() {
j=0
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
if [ $j -eq 5 ]; then mail.py; exit; fi
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)
if [ $n2 -gt 500 ]; then mail.py; exit; fi
fi
fi
sleep 10
done</code>18. Batch change passwords on multiple servers via SSH
<code>#!/bin/bash
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 {\n \"(yes/no)\" {send \"yes\r\";exp_continue}\n \"password:\" {send \"$PASS\r\";exp_continue}\n \"$USER@*\" {send \"echo '$NEW_PASS' |passwd --stdin $USER\r exit\r";exp_continue}\n }"
done</code>19. iptables auto‑block IPs with excessive request rates
<code># Block IPs with >200 requests per minute (Nginx example)
#!/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 (auth.log example)
DATE=$(date +"%b %d %H")
ABNORMAL_IP=$(tail -n10000 /var/log/auth.log | grep "$DATE" | awk '/Failed/{a[$(NF-3)]++} END {for(i in a) if(a[i]>5) print i}')
for IP in $ABNORMAL_IP; do
if [ $(iptables -vnL | grep -c "$IP") -eq 0 ]; then
iptables -A INPUT -s $IP -j DROP
echo "$(date +"%F %T") - iptables -A INPUT -s $IP -j DROP" >> ~/ssh-login-limit.log
fi
done</code>20. Block/Unblock IPs based on web access logs
<code>#!/bin/bash
logfile=/data/log/access.log
ipt=/sbin/iptables
ips=/tmp/ips.txt
block() {
d1=$(date -d "-1 minute" +%H%M)
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
}
minute=$(date +%M)
if [ $minute -eq 00 ] || [ $minute -eq 30 ]; then
unblock
block
else
block
fi</code>21. Validate user‑entered IP address
<code>#!/bin/bash
function check_ip(){
local IP=$1
if echo $IP | grep -E "^[0-9]{1,3}(\.[0-9]{1,3}){3}$" >/dev/null; then
if [[ $(echo $IP | awk -F. '{print ($1<=255 && $2<=255 && $3<=255 && $4<=255)}') == 1 ]]; then
echo "$IP available."
return 0
else
echo "$IP not available!"
return 1
fi
else
echo "Format error! Please input again."
return 1
fi
}
while true; do
read -p "Please enter IP: " IP
check_ip $IP && break
done</code>Written by
Efficient Ops
This public account is maintained by Xiaotianguo and friends, regularly publishing widely-read original technical articles. We focus on operations transformation and accompany you throughout your operations career, growing together happily.
0 followers
Reader feedback
How this landed with the community
Rate this article
Was this worth your time?
Discussion
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.