9 個實用 shell 指令碼,建議收藏!

語言: CN / TW / HK

關注公眾號:IT老哥,每天讀一篇乾貨技術文章,一年後你會發現一個不一樣的自己

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 $LOG_FILE |grep $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 "$IP") -eq 0 ]; then         iptables -I INPUT -s $IP -j DROP         echo "$(date +'%F_%T') $IP" >> /tmp/drop_ip.log     fi done

```

2.Linux 系統傳送告警指令碼

```

yum install mailx

vi /etc/mail.rc

set [email protected] smtp=smtp.163.com set [email protected] 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$HOST -u$USER -p$PASS -s -e "show databases;" 2>/dev/null |egrep -v "Database|information_schema|mysql|performance_schema|sys")

for DB in $DB_LIST; do     BACKUP_NAME=$BACKUP_DIR/${DB}_${DATE}.sql     if ! mysqldump -h$HOST -u$USER -p$PASS -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$HOST -u$USER -p$PASS -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=$BACKUP_DIR/${DB}_${DATE}     [ ! -d $BACKUP_DB_DIR ] && mkdir -p $BACKUP_DB_DIR &>/dev/null     TABLE_LIST=$(mysql -h$HOST -u$USER -p$PASS -s -e "use $DB;show tables;" 2>/dev/null)     for TABLE in $TABLE_LIST; do         BACKUP_NAME=$BACKUP_DB_DIR/${TABLE}.sql         if ! mysqldump -h$HOST -u$USER -p$PASS $DB $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=$LOG_DIR/$(date +"%Y-%m") LOG_FILE_LIST="default.access.log"

for LOG_FILE in $LOG_FILE_LIST; do     [ ! -d $LOG_MONTH_DIR ] && mkdir -p $LOG_MONTH_DIR     mv $LOG_DIR/$LOG_FILE $LOG_MONTH_DIR/${LOG_FILE}_${YESTERDAY_TIME} done

kill -USR1 $(cat /var/run/nginx.pid)

```

6.Nginx 訪問日誌分析指令碼

```

!/bin/bash

日誌格式: $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$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]}' $LOG_FILE |sort -k2 -nr |head -10 echo "----------------------"

echo "統計時間段訪問最多的IP" awk '$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" "$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 '$0~"'$NIC'"{print $2}' /proc/net/dev)     OLD_OUT=$(awk '$0~"'$NIC'"{print $10}' /proc/net/dev)     sleep 1     NEW_IN=$(awk  '$0~"'$NIC'"{print $2}' /proc/net/dev)     NEW_OUT=$(awk '$0~"'$NIC'"{print $10}' /proc/net/dev)     IN=$(printf "%.1f%s" "$((($NEW_IN-$OLD_IN)/1024))" "KB/s")     OUT=$(printf "%.1f%s" "$((($NEW_OUT-$OLD_OUT)/1024))" "KB/s")     echo "$IN $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}' $HOST_INFO); do     USER=$(awk -v ip=$IP 'ip==$1{print $2}' $HOST_INFO)     PORT=$(awk -v ip=$IP 'ip==$1{print $3}' $HOST_INFO)     TMP_FILE=/tmp/disk.tmp     ssh -p $PORT $USER@$IP 'df -h' > $TMP_FILE     USE_RATE_LIST=$(awk 'BEGIN{OFS="="}/^\/dev/{print $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: $PART_NAME Partition usage $USE_RATE%!"         fi     done done

```