30 Essential Bash Scripts for Linux Operations and Automation
This article compiles a comprehensive set of Bash scripts that demonstrate how to verify file consistency across servers, schedule log cleaning, monitor network traffic, count numeric characters in files, manage users and passwords, automate firewall rules, and perform various other Linux system administration tasks, providing ready-to-use code snippets for each scenario.
1. Detect file consistency between two servers
#!/bin/bash
######################################
# Detect file consistency between two servers
######################################
# Compare MD5 values of files in a directory on two hosts
dir=/data/web
b_ip=192.168.88.10
# Generate MD5 list on local host
find $dir -type f | xargs md5sum > /tmp/md5_a.txt
# Generate MD5 list on remote host
ssh $b_ip "find $dir -type f | xargs md5sum > /tmp/md5_b.txt"
scp $b_ip:/tmp/md5_b.txt /tmp
# Compare the two lists
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
done2. Hourly log cleanup and size recording
#!/bin/bash
#################################################################
# Run hourly; at 00:00 or 12:00 clear file contents, otherwise record 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
fi3. Monitor network interface traffic and log it
#!/bin/bash
#######################################################
# Log network traffic every minute (input/output) in bps
#######################################################
LANG=en
logfile=/tmp/$(date +%d).log
exec >> $logfile
while :; do
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 "####################"
# No sleep needed because sar already takes 59 seconds
done4. Count numbers per line and total numbers in a document
#!/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 "$line : $n_n"
done
echo "sum:$sum"5. Kill all specified scripts
# Kill processes matching a given name (e.g., scripts added to cron)
ps aux | grep "指定进程名" | grep -v grep | awk '{print $2}' | xargs kill -96. Download a file from an FTP server
#!/bin/bash
if [ $# -ne 1 ]; then
echo "Usage: $0 filename"
exit 1
fi
dir=$(dirname $1)
file=$(basename $1)
ftp -n -v <<EOF
open 192.168.1.10
user admin password
binary
cd $dir
get "$file"
EOF7. Read five numbers and report sum, min, max
#!/bin/bash
COUNT=1
SUM=0
MIN=1000
MAX=0
while [ $COUNT -le 5 ]; do
read -p "请输入1-100的整数:" INT
if ! [[ $INT =~ ^[0-9]+$ ]] || [ $INT -gt 100 ]; then
echo "输入必须是100以内的整数!"
exit 1
fi
SUM=$((SUM + INT))
[ $INT -lt $MIN ] && MIN=$INT
[ $INT -gt $MAX ] && MAX=$INT
((COUNT++))
done
echo "SUM: $SUM"
echo "MIN: $MIN"
echo "MAX: $MAX"8. Number guessing game
#!/bin/bash
num=$[RANDOM%100+1]
# echo $num # for debugging
while :; do
read -p "计算机生成了一个 1-100 的随机数,你猜: " guess
if [ $guess -eq $num ]; then
echo "恭喜,猜对了"
exit 0
elif [ $guess -gt $num ]; then
echo "Oops,猜大了"
else
echo "Oops,猜小了"
fi
done9. Monitor Nginx access log for 502 errors and restart php-fpm
#!/bin/bash
# Path to access log
log=/data/log/access.log
threshold=30 # 10% of last 300 lines (30 lines)
while :; do
err=$(tail -n 300 $log | grep -c '502')
if [ $err -ge $threshold ]; then
/etc/init.d/php-fpm restart 2>/dev/null
sleep 60
fi
sleep 10
done10. Assign command output to variables
# Example 1: Loop over words
for i in $(echo "4 5 6"); do
eval a$i=$i
done
echo $a4 $a5 $a6
# Example 2: Split brace expansion into variables
num=0
for i in $(eval echo $*); do
((num++))
eval node${num}="$i"
done
echo $node1 $node2 $node3
# Example 3: Array indexing
arr=(4 5 6)
INDEX1=${arr[0]}
INDEX2=${arr[1]}
INDEX3=${arr[2]}11. Batch rename files
# Example: rename article_*.html to bbs_*.html
for file in $(ls *html); do
mv $file bbs_${file#*_}
done
# Alternative using rename command
# rename article bbs *.html12. Delete lines containing letters in the first five lines and strip letters from lines 6‑10
# Assuming 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.txt13. 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 $sum14. Scan host ports
#!/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
done15. Print words with fewer than six letters from a sample sentence
#!/bin/bash
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
done16. Menu‑driven command executor
#!/bin/bash
while :; do
echo "*cmd menu* 1-date 2-ls 3-who 4-pwd 0-exit"
read -p "please input number :" n
case $n in
1) date ;;
2) ls ;;
3) who ;;
4) pwd ;;
0) break ;;
*) echo "please input number is [1-4]" ;;
esac
done17. Expect script for password‑less SSH command execution
# Inline expect example
#!/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 "df -h\r" }
expect "$USER@*" { send "exit\r" }
expect eof
EOF18. Create 10 users with random passwords and log them
#!/bin/bash
for u in $(seq -w 0 9); do
useradd user_$u
p=$(mkpasswd -s 0 -l 10)
echo "$p" | passwd --stdin user_$u
echo "user_$u $p" >> /tmp/userpassword
done19. Monitor httpd process count and restart 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++)); fi
if [ $j -eq 5 ]; then mail.py; exit; fi
done
}
while :; do
n=$(pgrep -c httpd)
if [ $n -gt 500 ]; then
/usr/local/apache2/bin/apachectl restart
if [ $? -ne 0 ]; then
check_service
else
sleep 60
n2=$(pgrep -c httpd)
[ $n2 -gt 500 ] && mail.py && exit
fi
fi
sleep 10
done20. Batch change passwords on remote servers via SSH and Expect
#!/bin/bash
OLD_INFO=old_pass.txt
NEW_INFO=new_pass.txt
while read IP USER PASS PORT; do
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}}
expect \"$USER@*\" {send \"echo '$NEW_PASS' | passwd --stdin $USER\r exit\r"}
expect eof
"
done < $OLD_INFO21. iptables auto‑block excessive web or SSH traffic
# Block IPs with >200 requests per minute (web)
#!/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]>200) print i}')
for IP in $ABNORMAL_IP; do
iptables -I INPUT -s $IP -j DROP
done
# Block IPs with >10 failed SSH logins per minute
#!/bin/bash
DATE=$(date +"%b %d %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
iptables -I INPUT -s $IP -j DROP
done22. Unblock IPs after traffic normalizes
#!/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 | uniq -c | awk '$1>100{print $2}' > $ips
while read ip; do
$ipt -I INPUT -p tcp --dport 80 -s $ip -j REJECT
echo "$(date +%F-%T) $ip" >> /tmp/badip.log
done < $ips
}
unblock(){
$ipt -nvL INPUT --line-numbers | awk '/0.0.0.0\/0/ && $2<10 {print $1}' | sort -nr | while read line; do
$ipt -D INPUT $line
done
$ipt -Z
}
if [ $d2 -eq 00 ] || [ $d2 -eq 30 ]; then
unblock
block
else
block
fi23. Validate whether a string is a correct IPv4 address
#!/bin/bash
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. '{if($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
}
check_ip 192.168.1.1
check_ip 256.1.1.1Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
