第十二章 Shell脚本编写及常见面试题(二)
发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,本章目录:12.11 屏蔽网站访问频繁的IP1)屏蔽每分钟访问超过200的IP方法1:以Nginx日志作为测试DATE=$(date +%d/%b/%Y:%H:%M)ABNORMAL_IP=$(tai
千家信息网最后更新 2026年11月01日第十二章 Shell脚本编写及常见面试题(二)
本章目录:
12.11 屏蔽网站访问频繁的IP
1)屏蔽每分钟访问超过200的IP
方法1:以Nginx日志作为测试
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}')#先tail防止文件过大,读取慢,数字可调整每分钟最大的访问量。awk不能直接过滤日志,因为包含特殊字符。for IP in $ABNORMAL_IP; do if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then iptables -I INPUT -s $IP -j DROP fidone方法2:通过建立连接数
ABNORMAL_IP=$(netstat -an |awk '$4~/:80$/ && $6~/ESTABLISHED/{gsub(/:[0-9]+/,"",$5);{a[$5]++}}END{for(i in a)if(a[i]>100)print i}')#gsub是将第五列(客户端IP)的冒号和端口去掉for IP in $ABNORMAL_IP; do if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then iptables -I INPUT -s $IP -j DROP fidone2)屏蔽每分钟SSH暴力破解超过10次的IP
方法1:通过lastb获取登录状态:
DATE=$(date +"%a %b %e %H:%M") #星期月天时分 %e单数字时显示7,而%d显示07ABNORMAL_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 -I INPUT -s $IP -j DROP fidone方法2:通过日志获取登录状态
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 fidone12.12 判断输入是否为IP
方法1:
function check_ip(){ IP=$1 VALID_CHECK=$(echo $IP|awk -F. '$1<=255&&$2<=255&&$3<=255&&$4<=255{print "yes"}') if echo $IP|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$">/dev/null; then if [ $VALID_CHECK == "yes" ]; then echo "$IP available." else echo "$IP not available!" fi else echo "Format error!" fi}check_ip 192.168.1.1check_ip 256.1.1.1方法2:
function check_ip(){ IP=$1 if [[ $IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then FIELD1=$(echo $IP|cut -d. -f1) FIELD2=$(echo $IP|cut -d. -f2) FIELD3=$(echo $IP|cut -d. -f3) FIELD4=$(echo $IP|cut -d. -f4) if [ $FIELD1 -le 255 -a $FIELD2 -le 255 -a $FIELD3 -le 255 -a $FIELD4 -le 255 ]; then echo "$IP available." else echo "$IP not available!" fi else echo "Format error!" fi}check_ip 192.168.1.1check_ip 256.1.1.1增加版:加个死循环,如果IP可用就退出,不可用提示继续输入,并使用awk判断
function check_ip(){ local IP=$1 VALID_CHECK=$(echo $IP|awk -F. '$1<=255&&$2<=255&&$3<=255&&$4<=255{print "yes"}') if echo $IP|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" >/dev/null; then if [ $VALID_CHECK == "yes" ]; then 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 [ $? -eq 0 ] && break || continuedone12.13 判断输入是否为数字
方法1:if [[ $1 =~ ^[0-9]+$ ]]; then echo "Is Number."else echo "No Number."fi方法2:if [ $1 -gt 0 ] 2>/dev/null; then echo "Is Number."else echo "No Number."fi
方法3:
echo $1 |awk '{print $0~/^[0-9]+$/?"Is Number.":"No Number."}' #三目运算符12.14 找出包含关键字的文件DIR=$1KEY=$2for FILE in $(find $DIR -type f); do if grep $KEY $FILE &>/dev/null; then echo "--> $FILE" fidone12.15 监控目录,将新创建的文件名追加到日志中
需安装inotify-tools软件包。
#!/bin/bashMON_DIR=/optinotifywait -mq --format %f -e create $MON_DIR |\while read files; do echo $files >> test.logdone12.16 多个网卡选择function local_nic() { local NUM ARRAY_LENGTH NUM=0 for NIC_NAME in $(ls /sys/class/net|grep -vE "lo|docker0"); do NIC_IP=$(ifconfig $NIC_NAME |awk -F'[: ]+' '/inet addr/{print $4}') if [ -n "$NIC_IP" ]; then NIC_IP_ARRAY[$NUM]="$NIC_NAME:$NIC_IP" #将网卡名和对应IP放到数组 let NUM++ fi done ARRAY_LENGTH=${#NIC_IP_ARRAY[*]} if [ $ARRAY_LENGTH -eq 1 ]; then #如果数组里面只有一条记录说明就一个网卡 NIC=${NIC_IP_ARRAY[0]%:*} return 0 elif [ $ARRAY_LENGTH -eq 0 ]; then #如果没有记录说明没有网卡 echo "No available network card!" exit 1 else #如果有多条记录则提醒输入选择 for NIC in ${NIC_IP_ARRAY[*]}; do echo $NIC done while true; do read -p "Please enter local use to network card name: " INPUT_NIC_NAME COUNT=0 for NIC in ${NIC_IP_ARRAY[*]}; do NIC_NAME=${NIC%:*} if [ $NIC_NAME == "$INPUT_NIC_NAME" ]; then NIC=${NIC_IP_ARRAY[$COUNT]%:*} return 0 else COUNT+=1 fi done echo "Not match! Please input again." done fi}local_nic如果有只有一个网卡就不选择。
12.17 查看网卡实时流量
#!/bin/bash# Description: Only CentOS6traffic_unit_conv() { local traffic=$1 if [ $traffic -gt 1024000 ]; then printf "%.1f%s" "$(($traffic/1024/1024))" "MB/s" elif [ $traffic -lt 1024000 ]; then printf "%.1f%s" "$(($traffic/1024))" "KB/s" fi}NIC=$1echo -e " In ------ Out"while true; do OLD_IN=$(awk -F'[: ]+' '$0~"'$NIC'"{print $3}' /proc/net/dev) OLD_OUT=$(awk -F'[: ]+' '$0~"'$NIC'"{print $11}' /proc/net/dev) sleep 1 NEW_IN=$(awk -F'[: ]+' '$0~"'$NIC'"{print $3}' /proc/net/dev) NEW_OUT=$(awk -F'[: ]+' '$0~"'$NIC'"{print $11}' /proc/net/dev) IN=$(($NEW_IN-$OLD_IN)) OUT=$(($NEW_OUT-$OLD_OUT)) echo "$(traffic_unit_conv $IN) $(traffic_unit_conv $OUT)" sleep 1done# 也可以通过ficonfig命令获取收发流量while true; do OLD_IN=$(ifconfig $NIC |awk -F'[: ]+' '/bytes/{print $4}') OLD_OUT=$(ifconfig $NIC |awk -F'[: ]+' '/bytes/{print $9}') sleep 1 NEW_IN=$(ifconfig $NIC |awk -F'[: ]+' '/bytes/{print $4}') NEW_OUT=$(ifconfig $NIC |awk -F'[: ]+' '/bytes/{print $9}') IN=$(($NEW_IN-$OLD_IN)) OUT=$(($NEW_OUT-$OLD_OUT)) echo "$(traffic_unit_conv $IN) $(traffic_unit_conv $OUT)" sleep 1done12.18 MySQL数据库备份
#!/bin/bashDATE=$(date +%F_%H-%M-%S)HOST=192.168.1.120DB=testUSER=bakPASS=123456MAIL="zhangsan@example.com lisi@example.com"BACKUP_DIR=/data/db_backupSQL_FILE=${DB}_full_$DATE.sqlBAK_FILE=${DB}_full_$DATE.zipcd $BACKUP_DIRif mysqldump -h$HOST -u$USER -p$PASS --single-transaction --routines --triggers -B $DB > $SQL_FILE; then zip $BAK_FILE $SQL_FILE && rm -f $SQL_FILE if [ ! -s $BAK_FILE ]; then echo "$DATE 内容" | mail -s "主题" $MAIL fielse echo "$DATE 内容" | mail -s "主题" $MAILfifind $BACKUP_DIR -name '*.zip' -ctime +14 -exec rm {} \;12.19 Nginx启动脚本
#!/bin/bash# Description: Only support RedHat system. /etc/init.d/functionsWORD_DIR=/data/project/nginx1.10DAEMON=$WORD_DIR/sbin/nginxCONF=$WORD_DIR/conf/nginx.confNAME=nginxPID=$(awk -F'[; ]+' '/^[^#]/{if($0~/pid;/)print $2}' $CONF)if [ -z "$PID" ]; then PID=$WORD_DIR/logs/nginx.pidelse PID=$WORD_DIR/$PIDfistop() { $DAEMON -s stop sleep 1 [ ! -f $PID ] && action "* Stopping $NAME" /bin/true || action "* Stopping $NAME" /bin/false}start() { $DAEMON sleep 1 [ -f $PID ] && action "* Starting $NAME" /bin/true || action "* Starting $NAME" /bin/false}reload() { $DAEMON -s reload}test_config() { $DAEMON -t}case "$1" in start) if [ ! -f $PID ]; then start else echo "$NAME is running..." exit 0 fi ;; stop) if [ -f $PID ]; then stop else echo "$NAME not running!" exit 0 fi ;; restart) if [ ! -f $PID ]; then echo "$NAME not running!" start else stop start fi ;; reload) reload ;; testconfig) test_config ;; status) [ -f $PID ] && echo "$NAME is running..." || echo "$NAME not running!" ;; *) echo "Usage: $0 {start|stop|restart|reload|testconfig|status}" exit 3 ;;esac12.20 选择SSH连接主机
写一个配置文件保存被监控主机SSH连接信息,文件内容格式:主机名 IP User Port
#!/bin/bashPS3="Please input number: "HOST_FILE=hostwhile true; do select NAME in $(awk '{print $1}' $HOST_FILE) quit; do [ ${NAME:=empty} == "quit" ] && exit 0 IP=$(awk -v NAME=${NAME} '$1==NAME{print $2}' $HOST_FILE) USER=$(awk -v NAME=${NAME} '$1==NAME{print $3}' $HOST_FILE) PORT=$(awk -v NAME=${NAME} '$1==NAME{print $4}' $HOST_FILE) if [ $IP ]; then echo "Name: $NAME, IP: $IP" ssh -o StrictHostKeyChecking=no -p $PORT -i id_rsa $USER@$IP # 密钥登录 break else echo "Input error, Please enter again!" break fi donedone本章写的Shell脚本例子都比较实用,在面试题中也经常出现,希望大家参考着多动手写写,不要复制粘贴就拿来跑,这样是学不会的!有问题请加×××流:323779636(Shell/Python运维开发群)
方法
网卡
文件
日志
输入
选择
主机
内容
数字
登录
脚本
主题
只有
数组
流量
状态
目录
监控
特殊
频繁
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
互联网加科技
江苏根荣互联网科技
科技和互联网公司
美国互联网科技
互联网科技公司有哪些
国外互联网科技网站
金融科技和互联网金融
互联网 科技馆
深圳国际航运科技和互联网
世界互联网科技公司市值排名
坤平互联网科技
链环科技传统企业怎么转型互联网
民营互联网公司国防科技
东莞新华互联网科技学校
互联网金融科技元年
城市宝互联网科技有限公司
富国互联网科技002692
互联网科技平台产品运营
长沙易易互联网科技有限公司
武汉亿视互联网科技有限公司
华服互联网科技靠谱吗
互联网最新的科技有限公司
丰台科技园 互联网
郑州华宇互联网科技
互联网科技大会案例
镁科技互联网资讯平台
安控科技rtu产品工业互联网
明优互联网科技有限公司
互联网科技年终奖
北京品多多互联网科技有限公司