在当今数字化时代,运维工作的重要性日益凸显。面对复杂多变的IT环境,高效的自动化工具和脚本成为每一位运维人员提升工作效率、保障系统稳定的关键利器。为了助力广大运维同行在日常工作中更加得心应手,我特此精心整理了一份实用的Shell脚本合集,旨在为大家提供一份“运维人的福利”,以期在繁琐的任务处理与系统管理中,助您一臂之力。
这份脚本集合凝聚了我个人在实际运维工作中积累的经验与智慧,涵盖了诸如服务器监控、故障排查、备份恢复、性能调优、自动化部署等诸多核心场景。每一行代码都经过实战打磨,力求简洁高效,易读易用,旨在适应各种复杂的运维环境,满足不同层次运维需求。无论您是初入运维领域的新人,还是经验丰富的资深专家,都能从中找到适合自己的工具,让繁杂的运维工作化繁为简,事半功倍。
在这里,我诚挚地邀请各位运维同仁随意拿取、自由分享这份Shell脚本资源。它们不仅是您日常工作的得力助手,更是交流学习、提升技能的良好素材。让我们共同携手,借助科技的力量,驱动运维工作的智能化、自动化进程,为构建稳定、高效的信息系统保驾护航。
1.Dos 攻击防范(自动屏蔽攻击 IP)
#!/bin/bash
DATE=$(date +%d/%b/%Y:%H:%M)
LOG_FILE=/usr/local/nginx/logs/demo2.access.log
ABNORMAL_IP=(tail−n5000(tail -n5000 LOG_FILE |grep DATE |awk '{a[DATE |awk '{a[DATE |awk '{a[1]++}END{for(i in
a)if(a[i]>10)print i}')
for IP in $ABNORMAL_IP; do
if [ (iptables−vnL|grep−c"(iptables -vnL |grep -c "IP") -eq 0 ]; then
iptables -I INPUT -s $IP -j DROP
echo "(date+′(date +'%F_%T') IP" >> /tmp/drop_ip.log
fi
done
2.Linux 系统发送告警脚本
# yum install mailx
# vi /etc/mail.rc
set from=baojingtongzhi@163.com smtp=smtp.163.com
set smtp-auth-user=baojingtongzhi@163.com smtp-auth-password=123456
set smtp-auth=login
3.MySQL 数据库备份单循环
#!/bin/bash
DATE=$(date +%F_%H-%M-%S)
HOST=localhost
USER=backup
PASS=123.com
BACKUP_DIR=/data/db_backup
DB_LIST=(mysql−h(mysql -hHOST -uUSER−pUSER -pPASS -s -e "show databases;" 2>/dev/null
|egrep -v "Database|information_schema|mysql|performance_schema|sys")
for DB in $DB_LIST; do
BACKUP_NAME=BACKUPDIR/BACKUP_DIR/{DB}_${DATE}.sql
if ! mysqldump -hHOST−uHOST -uUSER -pPASS−BPASS -B DB > $BACKUP_NAME 2>/dev/null;
then
echo "$BACKUP_NAME 备份失败!"
fi
done
4.MySQL 数据库备份多循环
#!/bin/bash
DATE=$(date +%F_%H-%M-%S)
HOST=localhost
USER=backup
PASS=123.com
BACKUP_DIR=/data/db_backup
DB_LIST=(mysql−h(mysql -hHOST -uUSER−pUSER -pPASS -s -e "show databases;" 2>/dev/null
|egrep -v "Database|information_schema|mysql|performance_schema|sys")
for DB in $DB_LIST; do
BACKUP_DB_DIR=BACKUPDIR/BACKUP_DIR/{DB}_${DATE}
[ ! -d BACKUP_DB_DIR ] && mkdir -pBACKUP_DB_DIR ] && mkdir -pBACKUP_DB_DIR ] && mkdir -p BACKUP_DB_DIR &>/dev/null
TABLE_LIST=(mysql−h(mysql -hHOST -uUSER−pUSER -pPASS -s -e "use $DB;show tables;"
2>/dev/null)
for TABLE in $TABLE_LIST; do
BACKUP_NAME=BACKUPDBDIR/BACKUP_DB_DIR/{TABLE}.sql
if ! mysqldump -hHOST−uHOST -uUSER -pPASSPASS DB TABLE>TABLE > BACKUP_NAME
2>/dev/null; then
echo "$BACKUP_NAME 备份失败!"
fi
done
done
5.Nginx 访问访问日志按天切割
#!/bin/bash
LOG_DIR=/usr/local/nginx/logs
YESTERDAY_TIME=$(date -d "yesterday" +%F)
LOG_MONTH_DIR=LOGDIR/LOG_DIR/(date +"%Y-%m")
LOG_FILE_LIST="default.access.log"
for LOG_FILE in $LOG_FILE_LIST; do
[ ! -d LOG_MONTH_DIR ] && mkdir -pLOG_MONTH_DIR ] && mkdir -pLOG_MONTH_DIR ] && mkdir -p LOG_MONTH_DIR
mv LOGDIR/LOG_DIR/LOG_FILE LOGMONTHDIR/LOG_MONTH_DIR/{LOG_FILE}_${YESTERDAY_TIME}
done
kill -USR1 $(cat /var/run/nginx.pid)
6.Nginx 访问日志分析脚本
#!/bin/bash
# 日志格式: remoteaddr−remote_addr - remote_user [timelocal]"time_local] "request" $status
bodybytessent"body_bytes_sent "http_referer" "httpuseragent""http_user_agent" "http_x_forwarded_for"
LOG_FILE=$1
echo "统计访问最多的10个IP"
awk '{a[1]++}END{print "UV:",length(a);for(v in a)print v,a[v]}'1]++}END{print "UV:",length(a);for(v in a)print v,a[v]}'1]++}END{print "UV:",length(a);for(v in a)print v,a[v]}' LOG_FILE |sort
-k2 -nr |head -10
echo "----------------------"
echo "统计时间段访问最多的IP"
awk '4>="[01/Dec/2018:13:20:25" &&4>="[01/Dec/2018:13:20:25" &&4>="[01/Dec/2018:13:20:25" && 4<="[27/Nov/2018:16:20:49"{a[$1]++}END{for(v
in a)print v,a[v]}' $LOG_FILE |sort -k2 -nr|head -10
echo "----------------------"
echo "统计访问最多的10个页面"
awk '{a[$7]++}END{print "PV:",length(a);for(v in a){if(a[v]>10)print v,a[v]}}'
$LOG_FILE |sort -k2 -nr
echo "----------------------"
echo "统计访问页面状态码数量"
awk '{a[7""7" "9]++}END{for(v in a){if(a[v]>5)print v,a[v]}}'
7.查看网卡实时流量脚本
#!/bin/bash
NIC=$1
echo -e " In ------ Out"
while true; do
OLD_IN=(awk′(awk '0~"'NIC'"{printNIC'"{printNIC'"{print 2}' /proc/net/dev)
OLD_OUT=(awk′(awk '0~"'NIC'"{printNIC'"{printNIC'"{print 10}' /proc/net/dev)
sleep 1
NEW_IN=(awk′(awk '0~"'NIC'"{printNIC'"{printNIC'"{print 2}' /proc/net/dev)
NEW_OUT=(awk′(awk '0~"'NIC'"{printNIC'"{printNIC'"{print 10}' /proc/net/dev)
IN=(printf"(printf "%.1f%s" "(((NEWIN−NEW_IN-OLD_IN)/1024))" "KB/s")
OUT=(printf"(printf "%.1f%s" "(((NEWOUT−NEW_OUT-OLD_OUT)/1024))" "KB/s")
echo "ININ OUT"
sleep 1
done
8.服务器系统配置初始化脚本
#/bin/bash
# 设置时区并同步时间
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
if ! crontab -l |grep ntpdate &>/dev/null ; then
(echo "* 1 * * * ntpdate time.windows.com >/dev/null 2>&1";crontab -l)
|crontab
fi
# 禁用selinux
sed -i '/SELINUX/{s/permissive/disabled/}' /etc/selinux/config
# 关闭防火墙
if egrep "7.[0-9]" /etc/redhat-release &>/dev/null; then
systemctl stop firewalld
systemctl disable firewalld
elif egrep "6.[0-9]" /etc/redhat-release &>/dev/null; then
service iptables stop
chkconfig iptables off
fi
# 历史命令显示操作时间
if ! grep HISTTIMEFORMAT /etc/bashrc; then
echo 'export HISTTIMEFORMAT="%F %T `whoami` "' >> /etc/bashrc
fi
# SSH超时时间
if ! grep "TMOUT=600" /etc/profile &>/dev/null; then
echo "export TMOUT=600" >> /etc/profile
fi
# 禁止root远程登录
sed -i 's/#PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
# 禁止定时任务向发送邮件
sed -i 's/^MAILTO=root/MAILTO=""/' /etc/crontab
# 设置最大打开文件数
if ! grep "* soft nofile 65535" /etc/security/limits.conf &>/dev/null; then
cat >> /etc/security/limits.conf << EOF
* soft nofile 65535
* hard nofile 65535
EOF
fi
# 系统内核优化
cat >> /etc/sysctl.conf << EOF
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_tw_buckets = 20480
net.ipv4.tcp_max_syn_backlog = 20480
net.core.netdev_max_backlog = 262144
net.ipv4.tcp_fin_timeout = 20
EOF
# 减少SWAP使用
echo "0" > /proc/sys/vm/swappiness
# 安装系统性能分析工具及其他
yum install gcc make autoconf vim sysstat net-tools iostat if
9.监控 100 台服务器磁盘利用率脚本
#!/bin/bash
HOST_INFO=host.info
for IP in (awk '/^[^#]/{print $1}'(awk '/^[^#]/{print $1}'(awk '/^[^#]/{print $1}' HOST_INFO); do
USER=(awk−vip=(awk -v ip=IP 'ip==1print$2′1{print $2}' HOST_INFO)
PORT=(awk−vip=(awk -v ip=IP 'ip==1print$3′1{print $3}' HOST_INFO)
TMP_FILE=/tmp/disk.tmp
ssh -p PORTPORT USER@IP′df−h′>IP 'df -h' > TMP_FILE
USE_RATE_LIST=(awk′BEGINOFS="="/\/dev/printNF,int(NF,int(5)′(awk 'BEGIN{OFS="="}/^\/dev/{print NF,int(NF,int(5)}' TMP_FILE)
for USE_RATE in $USE_RATE_LIST; do
PART_NAME=${USE_RATE%=*}
USE_RATE=${USE_RATE#*=}
if [ $USE_RATE -ge 80 ]; then
echo "Warning: PARTNAMEPartitionusagePART_NAME Partition usage USE_RATE%!"
fi
done
done
10.并发从数台机器中获取 hostname,并记录返回信息花费的时长,重定向到一个文件 hostname.txt 中,在全部完成后输出花费时长最短的那台机器的 CPU 信息。
#!bin/bash
# 所以主机,以空格分隔
ALL_HOSTS=(IP 地址 IP 地址)
for host in ${ALL_HOSTS[*]}
do
{
start_time=$(date +'%s')
ssh $host "hostname" &>/dev/null
sleep 2
stop_time=$(date +'%s')
time_consuming=$((stop_time-start_time))
echo "host:host: time_consuming" >>hostname.txt
}&
done
wait
host=(sort -n -k 2 hostname.txt | head -1 | awk -F':' '{print(sort -n -k 2 hostname.txt | head -1 | awk -F':' '{print(sort -n -k 2 hostname.txt | head -1 | awk -F':' '{print 1}')
ssh $host "top -b -n 1"
如果想上手操作练代码的同学们可以通过阿里云ecs服务器免费试用参与!
入口:新老同学免费试用