shell面试和工作常用脚本

https://www.nowcoder.com/ta/shell?fromPut=ad_baidu_sem_tibalinux&bd_vid=8699254905946388044
#########################################
https://www.cnblogs.com/cheyunhua/p/14768045.html
https://blog.csdn.net/F8qG7f9YD02Pe/article/details/123436805
https://blog.csdn.net/jj1130050965/article/details/122937350
https://blog.csdn.net/heian_99/category_9675115.html
1.Dos 攻击防范(自动屏蔽攻击IP)  https://blog.csdn.net/heian_99/article/details/104063402
#注意awk的各种参数、正则、使用方法https://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html,在一个文件中根据时间将ip取出,然后和异常数值做比较,超过异常数值的就通过iptables封堵
#!/bin/bash
DATE=$(date +%d/%b/%Y:%H:%M)
#nginx日志
LOG_FILE=/usr/local/nginx/logs/demo2.access.log
#分析ip的访问情况
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
#如果防火墙表里面没有过滤规则就增加,awk '{a[$1]++}的巧妙用法
    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
————————————————
版权声明:本文为CSDN博主「南宫乘风」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/heian_99/article/details/104063402
@@@@@按照一定量和时间检索某个文件,将ip捞出来归并,与100比较大小,超过100的用iptables封堵

封ip
 iptables -I INPUT -s 127.0.0.1 -j DROP 
解封ip
 iptables -D INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT 
防火墙端口操作
开启端口:
#/sbin/iptables -I
INPUT -p tcp –dport 80 -j ACCEPT
#/sbin/iptables -I
INPUT -p tcp –dport 22 -j ACCEPT
然后保存:
#/etc/rc.d/init.d/iptables save
关闭端口:
#/sbin/iptables -I
INPUT -p tcp –dport 80 -j DROP
#/sbin/iptables -I
INPUT -p tcp –dport 22 -j DROP
然后保存:
#/etc/rc.d/init.d/iptables save


2.Linux 系统发送告警脚本
https://blog.csdn.net/weixin_40816738/article/details/104475706

3.MySQL 数据库备份单循环  https://blog.csdn.net/heian_99/article/details/104061077
分库备份
#先看手动执行备份命令的时候是怎样一个命令,然后通过mysql命令登录数据库,过滤掉mysql本身自带的数据库,对剩下的数据库进行遍历备份
#mysqldump的用法  https://www.cnblogs.com/chenmh/p/5300370.html
mysqldump -uroot -pxxx -B A > A.sql
#!/bin/bash
DATE=$(date +%F_%H-%M-%S)
HOST=localhost
USER=backup
PASS=123.com
BACKUP_DIR=/data/db_backup
#grep和egrep的用法
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
分表备份

mysqldump -uroot -pxxx -A t > t.sql
#!/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
————————————————
版权声明:本文为CSDN博主「南宫乘风」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/heian_99/article/details/104061077
4.MySQL 数据库备份多循环

5.Nginx 访问访问日志按天切割   https://blog.51cto.com/msiyuetian/1880769
#1、每天的日志单独生成一个文件
#2、保留30天的访问日志
#3、编写脚本
#shell中的-d -z 以及字符串运算和逻辑运算的相关算法守则,实现每日一个文件只需要将目录下昨天的文件转移到另外一个目录下命名为昨天的名字,同时和crontab结合使用,在零点准时进行mv操作,将进程kill掉之后就会重新生成新的文件,删除30天以前的文件通过find来查找超过30天的文件,然后xargs rm给删除
#shell的算法  https://www.runoob.com/linux/linux-shell-basic-operators.html
#find的用法 https://www.cnblogs.com/peida/archive/2012/11/16/2773289.html
vim /usr/local/nginx/logs/nginx_log_rotate.sh
#! /bin/bash
logs_path="/usr/local/nginx/logs/"
log_name="access.log"
pid_path="/usr/local/nginx/logs/nginx.pid"
#日志文件集中存放的路径
[ -d /usr/local/nginx/logs/access_log ] || mkdir /usr/local/nginx/logs/access_log
access_logs_path="/usr/local/nginx/logs/access_log/"
#移动日志
mv ${logs_path}${log_name} ${access_logs_path}$(date --date="yesterday"+"%Y-%m-%d")_${log_name}
#生成新的access.log文件
kill -USR1 `cat ${pid_path}`
#删除一个月之前的日志
cd ${access_logs_path}
find . -ctime +30 -name "*access.log" |xargs rm -f
exit 0
脚本增加可执行权限
chmod a+x /usr/local/nginx/logs/nginx_log_rotate.sh
3、加入计划任务
每天凌晨运行脚本
crontab -e
00 00 * * * /usr/local/nginx/logs/nginx_log_rotate.sh
重启crond服务
service crond restart
-----------------------------------
©著作权归作者所有:来自51CTO博客作者M四月天的原创作品,请联系作者获取转载授权,否则将追究法律责任
nginx访问日志切割脚本
https://blog.51cto.com/msiyuetian/1880769

6.Nginx访问日志分析脚本  https://blog.csdn.net/heian_99/article/details/104061361
#!/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
#awk的END、BEGIN、sort 的各种常见参数,linux里面各种创建命令和参数详解 https://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858385.html
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]}}' $LOG_FILE |sort -k3 -nr
————————————————
版权声明:本文为CSDN博主「南宫乘风」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/heian_99/article/details/104061361

7.查看网卡实时流量脚本  https://blog.csdn.net/heian_99/article/details/104030173
#!/bin/bash
#方法是间隔1s,求进入间和流出间的差值,实时流量可以通过ss等命令查看也可以通过前一秒和后一秒的差值来展示一秒的流量情况
eth0=$1
echo  -e    "流量进入--流量传出    "
while true; do
    old_in=$(cat /proc/net/dev |grep $eth0 |awk '{print $2}')
    old_out=$(cat /proc/net/dev |grep $eth0 |awk '{print $10}')
    sleep 1
    new_in=$(cat /proc/net/dev |grep $eth0 |awk '{print $2}')
    new_out=$(cat /proc/net/dev |grep $eth0 |awk '{print $10}')
    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"
done
————————————————
版权声明:本文为CSDN博主「南宫乘风」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/heian_99/article/details/104030173

8.服务器系统配置初始化脚本  https://blog.csdn.net/heian_99/article/details/104027379
需求:
安装系统新能分析工具已经其他的工具
设置时区并同步时间
禁用selinux
清空防火墙默认策源
历史命令显示操作时间
禁止root远程登录
禁止定时任务发送邮件
设置最大打开文件数
减少Swap使用
系统内核参数的优化
脚本编写
#/bin/bash
# 安装系统性能分析工具及其他(这些工具的作用是什么,这些工具监控的项带表了哪项资源)
#各项简单命令的堆砌,
yum install gcc make autoconf vim sysstat net-tools iostat iftop iotp wget lrzsz lsof unzip openssh-clients net-tool vim ntpdate -y
# 设置时区并同步时间
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="%Y-%m-%d %H:%M:%S  `whoami` "' >> /etc/bashrc
fi
 
# SSH超时时间
if ! grep "TMOUT=600" /etc/profile &>/dev/null; then
    echo "export TMOUT=600" >> /etc/profile
fi
 
# 禁止root远程登录 切记给系统添加普通用户,给su到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
————————————————
版权声明:本文为CSDN博主「南宫乘风」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/heian_99/article/details/104027379

9.监控 100 台服务器磁盘利用率脚本  https://blog.csdn.net/heian_99/article/details/104031458
使用密钥登录
创建密钥====一直回车
ssh-keygen
把公钥复制到需要被控的服务器
ssh-copy-id [email protected]
在被传公钥的服务器的root的.ssh下
ls .ssh/
私钥登录公钥服务器
ssh -i .ssh/id_rsa [email protected]
脚本编写
#!/bin/bash
#awk的BEGIN、NF、NR
HOST_INFO=host.info
#awk的高级用法
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%!"
             echo "服务器$IP的磁盘空间占用过高,请及时处理" | mail -s "空间不足警告" 你的[email protected]
        else
            echo "服务器$IP的$PART_NAME目录空间良好"
        fi
    done
done
————————————————
版权声明:本文为CSDN博主「南宫乘风」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/heian_99/article/details/104031458

10.并发从数台机器中获取 hostname,并记录返回信息花费的时长,重定向到一个文件 hostname.txt中,在全部完成后输出花费时长最短的那台机器的 CPU 信息。(https://xie.infoq.cn/article/c0a3971c86d2b580d32047a4e)
#!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: $time_consuming" >>hostname.txt
}&
done

wait

host=$(sort -n -k 2 hostname.txt | head -1 | awk -F':' '{print $1}')

ssh $host "top -b -n 1"

11.统计/proc 目类下Linux进程相关数量信息,输出总进程数,runninq 进程数,stoped 进程数,sleeing进程数,zo mbie 进程数。  https://xie.infoq.cn/article/c0a3971c86d2b580d32047a4e
#!/bin/bash
#test的用法  https://www.runoob.com/linux/linux-shell-test.html
#awk取出文件对应进程名的列,然后case和我们设定的值匹配,如果匹配了,则对应数值加1
#统计一个文件中都有哪些分类,并且每个分类的个数是多少,最后的总数是多少,可以用case,也可以用if-else(判断字符是否相等)等逐个判断,对应的变量逐个计数
ALL_PROCESS=$(ls /proc/ | egrep '[0-9]+')

running_count=0
stoped_count=0
sleeping_count=0
zombie_count=0

for pid in ${ALL_PROCESS[*]}
do
    test -f /proc/$pid/status && state=$(egrep "State" /proc/$pid/status | awk '{print $2}')
    case "$state" in
        R)
            running_count=$((running_count+1))
        ;;
        T)
            stoped_count=$((stoped_count+1))
        ;;
        S)
            sleeping_count=$((sleeping_count+1))
        ;;
        Z)
            zombie_count=$((zombie_count+1))
            echo "$pid" >>zombie.txt
            kill -9 "$pid"
        ;;
    esac
done


echo -e "total: $((running_count+stoped_count+sleeping_count+zombie_count))\nrunning: $running_count\nstoped: $stoped_count\nsleeping: $sleeping_count\nzombie: $zombie_count"

12.把当前目录(包含子目录)下所有后缀为".sh"的文件后缀变更为".shell",之后删除每个文件的第二行。  https://xie.infoq.cn/article/c0a3971c86d2b580d32047a4e
#!/bin/bash
#将A变换为B其实就是通过mv将A迁移成B,前提是先拼好B,怎么拼B呢,用awk将需要改变的地方截取出来,然后加上需要拼成成的结尾,这样新的文件名就有了,sed的用法

ALL_SH_FILE=$(find . -type f -name "*.sh")
for file in ${ALL_SH_FILE[*]}
do
    filename=$(echo $file | awk -F'.sh' '{print $1}')
    new_filename="${filename}.shell"
    mv "$file" "$new_filename"
    sed -i '2d' "$new_filename"
done

13.判断目录/tmp/jstack是否存在,不存在则新建一个目录若存在则删除目录下所有内容。
每隔 1 小时打印 inceptor server 的 jstack 信息,并以 jstack_{当前时间}命名文件,每当目录下超过 10 个文件后,删除最旧的文件。  https://xie.infoq.cn/article/c0a3971c86d2b580d32047a4e
#ls的各种排序,比如按照时间、文件大小等等
#!/bin/bash
#shell的运算符

DIRPATH='/tmp/jstack'
CURRENT_TIME=$(date +'%F'-'%H:%M:%S')

if [ ! -d "$DIRPATH" ];then
    mkdir "$DIRPATH"
else
    rm -rf "$DIRPATH"/*
fi

cd "$DIRPATH"

while true
do
    sleep 3600
    # 这里需要将inceptor改后自己的java进程名称
    pid=$(ps -ef | grep 'inceptor' | grep -v grep | awk '{print $2}')
    jstack $pid >> "jstack_${CURRENT_TIME}"
    dir_count=$(ls | wc -l)
    if [ "$dir_count" -gt 10 ];then
       rm -f $(ls -tr | head -1)
    fi
done

14.从 test.loq中截取当天的所有gc 信息日志,并统计 gc 时间的平均值和时长最长的时间。  https://xie.infoq.cn/article/c0a3971c86d2b580d32047a4e
#!/bin/bash
#tr的用法https://www.runoob.com/linux/linux-comm-tr.html、awk的max和sum
#awk的高级用法awk '{sum+=$1} 
awk '{print $2}' hive-server2.log | tr -d ':' | awk '{sum+=$1} END {print "avg: ", sum/NR}' >>capture_hive_log.log
awk '{print $2}' hive-server2.log | tr -d ':' | awk '{max = 0} {if ($1+0 > max+0) max=$1} END {print "Max: ", max}'>>capture_hive_log.log

15.查找80端口请求数最高的前 20个IP地址,判断中间最小的请求数是否大于 500,如大于 500,则输出系统活动情况报告到 alert.txt,如果没有,则在 600s后重试,直到有输出为止。  https://xie.infoq.cn/article/c0a3971c86d2b580d32047a4e
#!/bin/bash
#awk高级用法awk -F'[ :]+' '/:22/{count[$4]++}
#查找80端口请求数最高的前 20个IP地址  https://www.cnblogs.com/yanans/p/13070762.html
#netstat -anlp|grep 80|grep tcp|awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -nr|head -n20
state="true"

while $state
do
    SMALL_REQUESTS=$(netstat -ant | awk -F'[ :]+' '/:22/{count[$4]++} END {for(ip in count) print count[ip]}' | sort -n | head -20 | head -1)
    if [ "$SMALL_REQUESTS" -gt 500 ];then
        sar -A > alert.txt
        state="false"
    else
        sleep 6
        continue
    fi
done    

16.将当前目录下大于10K的文件转移到/tmp 目录,再按照文件大小顺序,从大到小输出文件名。  https://xie.infoq.cn/article/c0a3971c86d2b580d32047a4e
#!/bin/bash


# 目标目录
DIRPATH='/tmp'
# 查看目录
FILEPATH='.'

find "$FILEPATH" -size +10k -type f | xargs -i mv {} "$DIRPATH"
ls -lS "$DIRPATH" | awk '{if(NR>1) print $NF}'

17.企业微信告警(https://www.jianshu.com/p/0758e04cde0d)
#!/bin/sh
expireTime=7200
dbFile="db.json"
corpid=xxx
corpsecret=xxx
touser="xxx"
toparty="xxx"
agentid="xxx"
content="服务器快崩了,你还在这里吟诗作对?"

# s 为秒,m 为 分钟,h 为小时,d 为日数  
interval=1s

## 发送报警信息
sendMsg(){
    if [ ! -f "$dbFile" ];then
            touch "$dbFile"
    fi

    # 获取token
    req_time=`jq '.req_time' $dbFile`
    current_time=$(date +%s)
    refresh=false
    if [ ! -n "$req_time" ];then
            refresh=true
    else
            if [ $((current_time-req_time)) -gt $expireTime ];then
                refresh=true
            fi
    fi
    if $refresh ;then
        req_access_token_url=https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$corpid\&corpsecret=$corpsecret
        access_res=$(curl -s -G $req_access_token_url | jq -r '.access_token')

        ## 保存文件
        echo "" > $dbFile
        echo -e "{" > $dbFile
        echo -e "\t\"access_token\":\"$access_res\"," >> $dbFile
        echo -e "\t\"req_time\":$current_time" >> $dbFile
        echo -e "}" >> $dbFile

        echo ">>>刷新Token成功<<<"
    fi 

    ## 发送消息
    msg_body="{\"touser\":\"$touser\",\"toparty\":\"$toparty\",\"msgtype\":\"text\",\"agentid\":$agentid,\"text\":{\"content\":\"$content\"}}"
    access_token=`jq -r '.access_token' $dbFile`
    req_send_msg_url=https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=$access_token
    req_msg=$(curl -s -H "Content-Type: application/json" -X POST -d $msg_body $req_send_msg_url | jq -r '.errmsg')

    echo "触发报警发送动作,返回信息为:" $req_msg 
    
}


loopMonitor(){
    echo 'loop'
    flag=`uptime | awk '{printf "%.2f\n", $11 "\n"}'`

    
    # 0.7 这个阈值可以视情况而定,如cpu核数为n,则可以设置为0.7 * n  具体视情况而定
    c=$(echo "$flag > 0.7" | bc)

    echo ">>>>>>>>>>>>>>>>>>`date`<<<<<<<<<<<<<<<<<<"
    free -m | awk 'NR==2{printf "Memory Usage: %s/%sMB (%.2f%%)\n", $3,$2,$3*100/$2 }'
    df -h | awk '$NF=="/"{printf "Disk Usage: %d/%dGB (%s)\n", $3,$2,$5}'
    uptime | awk '{printf "CPU Load: %.2f\n", $11 "\n"}'
    echo ">>>>>>>>>>>>>>>>>>end<<<<<<<<<<<<<<<<<<"
    
    if [ $c -eq 1  ];then
         sendMsg
    fi
}


while true; do
    loopMonitor
    sleep $interval
done
######################################
https://blog.51cto.com/u_14241151/2365809
function sendmsg() {

CorpID=“ww3c6298264d839e2f”
Secret=“YvyMQpMRIoXtdQRWo0RNkMBTZnHWKvBwC3ILkyuCsKQ”
agentid=1000002

GURL=“ https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=CorpID&corpsecret=Secret”
Gtoken=$(/usr/bin/curl -s -G $GURL|awk -F" ‘{print $10}’)

#echo Gtoken PURL="https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=GtokenPURL="https://qyapi.weixin.qq.com/cgi−bin/message/send?access 
t

 oken=Gtoken"

Ip=$(ip a |grep ens33 |grep inet|awk -F “/” ‘{ print $1 }’ |awk -F " " ‘{ print $2 }’)

/usr/bin/curl --data-ascii ‘{
“touser”: “@all”,
“toparty”: “2”,
“msgtype”: “text”,
“agentid”: “1000002”,
“text”: {“content”: "’“警告:[msg]\n主机:[`uname -n`]\n日期:[(date +%F-%T)]\n地址:[$Ip]”'"},
“safe”:“0”

}’ $PURL >/dev/null 2>&1
}
-----------------------------------
©著作权归作者所有:来自51CTO博客作者宁宁宁宁123的原创作品,请联系作者获取转载授权,否则将追究法律责任
shell脚本实现企业微信报警
https://blog.51cto.com/u_14241151/2365809

18.FTP客户端

19.SSH客户端

20.Saltstack 客户端

21.vCenter 客户端

22.获取域名ssl 证书过期时间  https://blog.csdn.net/woshizhangliang999/article/details/90646180
需要两个文件,一个用于存储域名信息,另一个是检测脚本
注意:这两个文件是在一个目录下  

domain_ssl.info 【存储域名信息】
[root@mini05 20180930]# cat domain_ssl.info 
# 检测百度域名
www.baidu.com:443
1
2
3
check_domain_time.sh 【检测脚本】
[root@mini05 20180930]# cat check_domain_time.sh 
#!/bin/bash
################ Version Info ##################
# Create Date: 2018-09-29
# Author:      Zhang
# Mail:        [email protected]
# Version:     1.0
# Attention:   通过域名获取证书的过期时间
################################################
# V1.0.0 2018-09-29 脚本编写    张
#      1.通过域名获取证书的过期时间
################################################

# 加载环境变量
. /etc/profile
. ~/.bash_profile
. /etc/bashrc

# 脚本所在目录即脚本名称
script_dir=$( cd "$( dirname "$0"  )" && pwd )
script_name=$(basename ${0})
#openssl的常见用法
readFile="${script_dir}/domain_ssl.info"
grep -v '^#' ${readFile} | while read line;do #读取存储了需要监测的域名的文件
    # echo "${line}"
    get_domain=$(echo "${line}" | awk -F ':' '{print $1}')
    get_port=$(echo "${line}" | awk -F ':' '{print $2}')

    # echo ${get_domain}
    # echo "${get_port}"
    # echo "======"

    END_TIME=$(echo | openssl s_client -servername ${get_domain}  -connect ${get_domain}:${get_port} 2>/dev/null | openssl x509 -noout -dates |grep 'After'| awk -F '=' '{print $2}'| awk -F ' +' '{print $1,$2,$4 }' )
    #使用openssl获取域名的证书情况,然后获取其中的到期时间
    END_TIME1=$(date +%s -d "$END_TIME") #将日期转化为时间戳
    NOW_TIME=$(date +%s -d "$(date | awk -F ' +'  '{print $2,$3,$6}')") #将目前的日期也转化为时间戳

    RST=$(($(($END_TIME1-$NOW_TIME))/(60*60*24))) # 到期时间减去目前时间再转化为天数

    echo "${RST}"
done
————————————————
版权声明:本文为CSDN博主「LightZhang666」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/woshizhangliang999/article/details/90646180

23.发送今天的天气预报以及未来的天气超势图(https://www.cnblogs.com/chenyu86784/p/12910759.html)
#!/bin/bash
#sed的高级用法  https://www.cnblogs.com/ggjucheng/archive/2013/01/13/2856901.html
curl 'https://free-api.heweather.net/s6/weather/forecast?location=wuhan&key=xxxxxxx' &> /weather/weather.txt
sun_up=$(cat weather.txt | sed 's/,/\n/g' | grep "sr" | sed 's/"/\n/g'|sed '1,3d' |sed '2,15d')
sun_down=$(cat weather.txt | sed 's/,/\n/g' | grep "ss" | sed 's/"/\n/g'|sed '1,3d' |sed '2,15d')
moon_up=$(cat weather.txt | sed 's/,/\n/g' | grep "mr" | sed 's/"/\n/g'|sed '1,3d' |sed '2,15d')
moon_down=$(cat weather.txt | sed 's/,/\n/g' | grep "ms" | sed 's/"/\n/g'|sed '1,3d' |sed '2,15d')
probability=$(cat weather.txt | sed 's/,/\n/g' | grep "pop" | sed 's/"/\n/g'|sed '1,3d' |sed '2,15d')
day=$(cat weather.txt | sed 's/,/\n/g' | grep "cond_txt_d" | sed 's/:/\n/g' |sed '3,6d'|sed '1d'|sed 's/"//g')
night=$(cat weather.txt | sed 's/,/\n/g' | grep "cond_txt_n" | sed 's/:/\n/g' |sed '3,6d'|sed '1d'|sed 's/"//g')
max=$(cat weather.txt | sed 's/,/\n/g' | grep "tmp_max" | sed 's/:/\n/g' |sed '3,6d'|sed '1d'|sed 's/"//g')
min=$(cat weather.txt | sed 's/,/\n/g' | grep "tmp_min" | sed 's/:/\n/g' |sed '3,6d'|sed '1d'|sed 's/"//g')

echo "美好的清晨,今天日出时间为${sun_up};今天白天天气为:${day},最高气温${max}度,最低气温${min}度;降水概率为${probability}%,今天的日落会在${sun_down},每一天都要开心,加油!" |mail -v -s "早安" [email protected]

24.SVN 完整备份  https://my.oschina.net/vhghhd/blog/351785

#!/bin/bash
#############################################################
#       svn backup
# command: svnbackup.sh [dump|hotcopy|rsync|load] [all|other]
# args:
#      dump: backup svn repos
#             all: backup all
#           other: backup the oldversion to newversion
#   hotcopy: reservd
#     rsync: reservd
#      load: load all repos to a new repos
#############################################################
 
##############################
#  use svnlook to look the 
#  newest version of repos
##############################
LookSvnNewVersion()
{
    v=`svnlook youngest $1`
    return $v
}
 
##############################
#  write the newest version 
#  to the file which is
#  named .oldsvnversion
##############################
WriteVersionToFile()
{
    echo $1 > $2
}
 
##############################
#  read the old version 
#  from the file which is
#  named .oldsvnversion
##############################
ReadOldVersionFromFile()
{
    v=`cat $1`
    return $v
}
 
 
# the svnpath and the svnversionbackup file path 
svnpath=/home/kehui/AllDisk/UbtHome/svn/project
svnversionfile=/home/kehui/.oldsvnversion
svnbackuppath=/home/kehui/AllDisk/Win7G/svnbackup
date=`date +%y%m%d`
if [ ! -f "$svnversionfile" ];then
    touch $svnversionfile
fi
 
# read the old version
oldversion=0
ReadOldVersionFromFile $svnversionfile
oldversion=$?
 
# write the new version
LookSvnNewVersion $svnpath
newversion=$?
WriteVersionToFile $newversion $svnversionfile
 
# if the args count < 1 , exit
if [ $# -lt 2 ];then
    echo "the args is too short"
    exit
fi
 
# judge the args
if [ $1 == "dump" ];then
    if [ $2 == "all" ];then
        echo "now begin to dump all repos"
        echo 1| sudo -S svnadmin dump $svnpath > $svnbackuppath/$date-dump
    elif [ $2 == "other" ];then
        if [ $oldversion -lt $newversion ];then
            echo "now begin to dump oldversion-newversion"
            if [ $oldversion -eq 0 ];then
                echo 1 | sudo -S svnadmin dump $svnpath -r $oldversion:$newversion > $svnbackuppath/$date-$oldversion-$newversion.dump
            else
                echo 1 | sudo -S svnadmin dump $svnpath -r $oldversion:$newversion --incremental > $svnbackuppath/$date-$oldversion-$newversion.dump-$date
            fi
        else
            echo "the oldversion >= newversion,donot have to backup"
            exit
        fi
    else
        echo "dump Error args."
    fi
elif [ $1 == "hotcopy" ];then
    echo "hotcopy"
elif [ $1 == "rsync" ];then
    echo "rsync"
elif [ $1 == "load" ];then
    if [ -f $2 ];then
        echo 1 | sudo -S svnadmin create $svnpath-new
        echo 1 | sudo -S svnadmin load $svnpath-new < $2
    else
        echo "the $2 is not exist,exit"
        exit
    fi
else
    echo "Error args."
fi

25.zabbix 监控用户密码过期

26.构建本地YUM  https://www.cnblogs.com/foxsir/p/5371342.html
#!/bin/sh

#请下载系统版本对应的"deltarpm-version.el6.x86_64.rpm python-deltarpm-version.el6.x86_64.rpm 
#createrepo-version.noarch.rpm",放到脚本对应的同级目录
#如何定义函数
set -e

function CheckRoot()
{
#check if currect use is root user
CUR_USER=`whoami`
if [ $CUR_USER != 'root' ]
then
      echo 'The operation will modify system files,you should be  root!'
  exit 1
fi
}

function MkDir()
{
if [ ! -d $1 ]
then
  mkdir $1 > /dev/null
fi
}

function RollBack()
{
ORIG_DIR=`pwd`
cd /etc/yum.repos.d > /dev/null
MkDir /ect/yum.repos.d/configYum_rb
mv *.repo configYum_rb/ > /dev/null
mv backup/*.repo . > /dev/null
rm -fr backup/ configYum_rb/ > /dev/null
yum clean all > /dev/null
yum makecache > /dev/null
yum repolist all
}

function Create()
{
echo 'Begin to create local yum source ... ...'
ORIG_DIR=`pwd`

#backup currect config
if [ ! -d "/etc/yum.repos.d" ]
  then
    echo '/etc/yum.repos.d is not existed , please check your system!'
    exit 1
  fi

cd /etc/yum.repos.d > /dev/null
MkDir /etc/yum.repos.d/backup
mv ./*.repo backup/

#create local.repo
cat >> local.repo << EOF
[localrepo]
name=localrepo
baseurl=file://$1
gpgcheck=0
enabled=1
EOF

retrpm=`rpm -qa | grep deltarpm`
if [ -z "$retrpm" ]
then
  rpm -ivh $ORIG_DIR/deltarpm-.*.rpm > /dev/null
  rpm -ivh $ORIG_DIR/python-deltarpm-.*.rpm > /dev/null
fi

#check if createrepo if existed
which createrepo > /dev/null

if [ $? -eq 1 ]
then
  rpm -ivh $ORIG_DIR/createrepo.*.noarch.rpm > /dev/null
  if [ $? -ne 0 ]
  then
    echo 'Install createrepo failed !'
    exit 1
  fi
fi

createrepo $1 > /dev/null

if [ $? -ne 0]
then
  echo 'create repo failed !'
  exit 1
fi

yum clean all > /dev/null
yum makecache > /dev/null
yum repolist all
}

function Help()
{
cat < There are 2 ways to call this script, for example:
1. To create a local Yum source: ./configYum.sh /tmp/packages
2. To rollback previous operation: ./configYum.sh b
EOF
}

function Main()
{
if [ $# -ne 1 ]
then
  Help
elif [ -d $1 ]
then
  CheckRoot
  Create $*
elif [ $1 = 'b' ]
then
  CheckRoot
  RolllBack
else
  Help
fi
}

Main $*  
  
27.备份当前日期文件  https://www.cnblogs.com/SimonHu1993/p/11511191.html
#!/bin/bash
#date的各种用法,获取对应的时间  https://www.cnblogs.com/weq0805/p/15249428.html
#一月前
historyTime=$(date "+%Y-%m-%d %H" -d '1 month ago')
echo ${historyTime}
historyTimeStamp=$(date -d "$historyTime" +%s)
echo ${historyTimeStamp}
 
#一周前
$(date "+%Y-%m-%d %H" -d '7 day ago')
 
#本月一月一日
date_this_month=`date +%Y%m01`
 
#一天前
date_today=`date -d '1 day ago' +%Y%m%d`
 
#一小时前
$(date "+%Y-%m-%d %H" -d '-1 hours')
复制代码
备份和删除前两个月的备份文件

复制代码
#!/bin/sh
source /etc/profile
#获取当前日期
ymd=`date +%Y%m%d`;
#获取上2个月
historyTime=$(date "+%Y%m" -d '2 month ago')
#打印日期
echo ${historyTime}
rm -rf ci_admin.jar.bak-$historyTime*
cp ci_admin.jar ci_admin.jar.bak-$ymd

29.批量创建多少个用户并设置密码  https://blog.csdn.net/heian_99/article/details/104028407
#!/bin/bash
#random创建随机数,cut命令用法 https://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858385.html
USER_LIST=$@
USER_FILE=./user.info
for USER in $USER_LIST;do
    if ! id $USER &>/dev/null; then
        PASS=$(echo $RANDOM |md5sum |cut -c 1-8)
        useradd $USER
        echo $PASS | passwd --stdin $USER &>/dev/null
        echo "$USER   $PASS" >> $USER_FILE
        echo "$USER User create successful."
    else
        echo "$USER User already exists!"
    fi
done

30.快速在Ubuntu 20.04上架设LAMP服务器及WordPress 博客  https://blog.csdn.net/heian_99/article/details/104039886
#!/bin/bash
NGINX_V=1.15.6
PHP_V=5.6.36
TMP_DIR=/tmp 
INSTALL_DIR=/usr/local 
PWD_C=$PWD
 
echo
echo -e "\tMenu\n"
echo -e "1. Install Nginx"
echo -e "2. Install PHP"
echo -e "3. Install MySQL"
echo -e "4. Deploy LNMP"
echo -e "9. Quit"
 
function command_status_check() {
    if [ $? -ne 0 ]; then
        echo $1
        exit
    fi 
}
 
function install_nginx() {
    cd $TMP_DIR
    yum install -y gcc gcc-c++ make openssl-devel pcre-devel wget
    wget http://nginx.org/download/nginx-${NGINX_V}.tar.gz
    tar zxf nginx-${NGINX_V}.tar.gz
    cd nginx-${NGINX_V}
    ./configure --prefix=$INSTALL_DIR/nginx \
    --with-http_ssl_module \
    --with-http_stub_status_module \
    --with-stream
    command_status_check "Nginx - 平台环境检查失败!"
    make -j 4 
    command_status_check "Nginx - 编译失败!"
    make install
    command_status_check "Nginx - 安装失败!"
    mkdir -p $INSTALL_DIR/nginx/conf/vhost
    alias cp=cp ; cp -rf $PWD_C/nginx.conf $INSTALL_DIR/nginx/conf
    rm -rf $INSTALL_DIR/nginx/html/*
    echo "ok" > $INSTALL_DIR/nginx/html/status.html
    echo '' > $INSTALL_DIR/nginx/html/status.php
    $INSTALL_DIR/nginx/sbin/nginx
    command_status_check "Nginx - 启动失败!"
}
 
function install_php() {
    cd $TMP_DIR
    yum install -y gcc gcc-c++ make gd-devel libxml2-devel \
        libcurl-devel libjpeg-devel libpng-devel openssl-devel \
        libmcrypt-devel libxslt-devel libtidy-devel
    wget http://docs.php.net/distributions/php-${PHP_V}.tar.gz
    tar zxf php-${PHP_V}.tar.gz
    cd php-${PHP_V}
    ./configure --prefix=$INSTALL_DIR/php \
    --with-config-file-path=$INSTALL_DIR/php/etc \
    --enable-fpm --enable-opcache \
    --with-mysql --with-mysqli --with-pdo-mysql \
    --with-openssl --with-zlib --with-curl --with-gd \
    --with-jpeg-dir --with-png-dir --with-freetype-dir \
    --enable-mbstring --enable-hash
    command_status_check "PHP - 平台环境检查失败!"
    make -j 4 
    command_status_check "PHP - 编译失败!"
    make install
    command_status_check "PHP - 安装失败!"
    cp php.ini-production $INSTALL_DIR/php/etc/php.ini
    cp sapi/fpm/php-fpm.conf $INSTALL_DIR/php/etc/php-fpm.conf
    cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
    chmod +x /etc/init.d/php-fpm
    /etc/init.d/php-fpm start
    command_status_check "PHP - 启动失败!"
}
 
read -p "请输入编号:" number
case $number in
    1)
        install_nginx;;
    2)
        install_php;;
    3)
        install_mysql;;
    4)
        install_nginx
        install_php
        ;;
    9)
        exit;;
esac

31.每天自动备份 MySQL 数据库  https://blog.csdn.net/heian_99/article/details/114079900
#!/bin/bash
USER=jumpserver
PASS=jumpserver
DBDIR=/databak/Data_Backup
#DAY=`date  +%Y%m%d`
#年月
MONTH=`date +%Y%m`
#日期时间
DT=`date '+%Y%m%d%H%M'`
#主机ip
DBIP=`cat /etc/sysconfig/network-scripts/ifcfg-eth0 | grep IPADDR | awk -F '"' '{print $2}'`
#创建备份目录
mkdir -p $DBDIR/$DBIP/$MONTH
备份数据库
for  dbname in jumpserver
do
    mysqldump  -u$USER   -p$PASS -R    --single-transaction  $dbname 2>>$DBDIR/$DBIP/$MONTH/error-$DT.log   |gzip  > $DBDIR/$DBIP/$MONTH/$dbname-$DBIP-$DT.sql.gz
      # 生成md5sum文件
     md5sum $DBDIR/$DBIP/$MONTH/$dbname-$DBIP-$DT.sql.gz > $DBDIR/$DBIP/$MONTH/$dbname-$DBIP-$DT.sql.gz.MD5
done
 
# check and delete old datafile.
#删除超过30天的文件,并删除目录
#find、exec、xargs等用法
#https://blog.csdn.net/even160941/article/details/89512801
#exec的用法http://ipcmen.com/exec

del_backup_dir=/databak/Data_Backup/$DBIP
cd $del_backup_dir
if [ $? = 0 ]; then
        find ./ -type f -mtime +30 -exec rm -rf {} \; >/dev/null 2>&1
        find -depth -type d -empty -exec rmdir {} \;
fi
 
#压缩备份
#mysqldump -uroot -proot --databases abc 2>/dev/null |gzip >/abc.sql.gz
#还原
#gunzip -c abc.sql.gz |mysql -uroot -proot abc

35.生成10个随机数保存于数组中并找出其最大值和最小值  https://blog.csdn.net/liangkaiping0525/article/details/90512142(这个全部都换了)

#!/bin/bash
#随机生成的数中0是最小的,先把0赋值给min和max,然后在每次的循环过程中,和最大最小比较,如果比最大的大就赋值给最大的,如果没最小的小就赋值给最小的
declare -a rand
declare -i max min
 
for i in {0..9}; do
        rand[$i]=$RANDOM
        echo ${rand[$i]}
        if [ $i -eq 0 ];then
                max=${rand[$i]}
                min=${rand[$i]}
        elif [ ${rand[$i]} -gt $max ];then
        #逐个比较,大的赋值给max        
                 max=${rand[$i]}
        elif [ ${rand[$i]} -lt $min ];then
        #逐个比较,小的赋值给min        
                min=${rand[$i]}
        fi
done
 
echo "Max:$max"
echo "Min:$min"
————————————————
版权声明:本文为CSDN博主「my_qq_990814268」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/liangkaiping0525/article/details/90512142

39.一键查看服务器利用率  https://blog.csdn.net/heian_99/article/details/104028739
#!/bin/bash
function cpu(){
    util=$(vmstat | awk '{if(NR==3)print $13+$14}')
    iowait=$(vmstat | awk '{if(NR==3)print $16}')
    echo "CPU -使用率:${util}% ,等待磁盘IO相应使用率:${iowait}:${iowait}%"
}
function memory (){
    total=`free -m |awk '{if(NR==2)printf "%.1f",$2/1024}'`
    used=`free -m |awk '{if(NR==2) printf "%.1f",($2-$NF)/1024}'`
    available=`free -m |awk '{if(NR==2) printf "%.1f",$NF/1024}'`
    echo "内存 - 总大小: ${total}G , 使用: ${used}G , 剩余: ${available}G"
}
disk(){
    fs=$(df -h |awk '/^\/dev/{print $1}')
    for p in $fs; do
        mounted=$(df -h |awk '$1=="'$p'"{print $NF}')
        size=$(df -h |awk '$1=="'$p'"{print $2}')
        used=$(df -h |awk '$1=="'$p'"{print $3}')
        used_percent=$(df -h |awk '$1=="'$p'"{print $5}')
        echo "硬盘 - 挂载点: $mounted , 总大小: $size , 使用: $used , 使用率: $used_percent"
    done 
}
function tcp_status() {
    summary=$(ss -antp |awk '{status[$1]++}END{for(i in status) printf i":"status[i]" "}')
    echo "TCP连接状态 - $summary"
}
cpu
memory
disk
tcp_status

40.找出占用CPU 内存过高的进程
#!/bin/bash
echo "-------------------CUP占用前10排序--------------------------------"
ps -eo user,pid,pcpu,pmem,args --sort=-pcpu  |head -n 10
echo "-------------------内存占用前10排序--------------------------------"
ps -eo user,pid,pcpu,pmem,args --sort=-pmem  |head -n 10

43.批量检测网站是否异常并邮队件通知  https://blog.csdn.net/heian_99/article/details/104032121
#curl命令常用用法  https://blog.csdn.net/zhujy5/article/details/88391070
#!/bin/bash  
URL_LIST="www.baidu.com www.ctnrs.com www.der-matech.net.cn www.der-matech.com.cn www.der-matech.cn www.der-matech.top www.der-matech.org"
for URL in $URL_LIST; do
    FAIL_COUNT=0
#对一个域名检测3次,如果1次成功则退出,如果3次都失败则退出,并邮件告警通知
    for ((i=1;i<=3;i++)); do
        HTTP_CODE=$(curl -o /dev/null --connect-timeout 3 -s -w "%{http_code}" $URL)
        if [ $HTTP_CODE -eq 200 ]; then
            echo "$URL OK"
            break
        else
            echo "$URL retry $FAIL_COUNT"
            let FAIL_COUNT++
        fi
    done
    if [ $FAIL_COUNT -eq 3 ]; then
        echo "Warning: $URL Access failure!"
        echo "网站$URL坏掉,请及时处理" | mail -s "$URL网站高危" [email protected]
    fi
done

44.批量主机远程执行命令脚本  https://blog.csdn.net/heian_99/article/details/104039706
#!/bin/bash
#expect
COMMAND=$*
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)
    PASS=$(awk -v ip=$IP 'ip==$1{print $4}' $HOST_INFO)
    expect -c "
       spawn ssh -p $PORT $USER@$IP
       expect {
          \"(yes/no)\" {send \"yes\r\"; exp_continue}
          \"password:\" {send \"$PASS\r\"; exp_continue}
          \"$USER@*\" {send \"$COMMAND\r exit\r\"; exp_continue}
       }
    "
    echo "-------------------"
done

46.监控MySQL主从同步状态是否异常脚本  https://blog.csdn.net/heian_99/article/details/104040379
#!/bin/bash  
HOST=localhost
USER=root
PASSWD=123.com
#awk的高级用法awk '/Slave_.*_Running:/
IO_SQL_STATUS=$(mysql -h$HOST -u$USER -p$PASSWD -e 'show slave status\G' 2>/dev/null |awk '/Slave_.*_Running:/{print $1$2}')
for i in $IO_SQL_STATUS; do
    THREAD_STATUS_NAME=${i%:*}
    THREAD_STATUS=${i#*:}
    if [ "$THREAD_STATUS" != "Yes" ]; then
        echo "Error: MySQL Master-Slave $THREAD_STATUS_NAME status is $THREAD_STATUS!" |mail -s "Master-Slave Staus" [email protected]
    fi
done

50.自动发布Java项目(Tomcat) https://blog.csdn.net/heian_99/article/details/104062470
#!/bin/bash
DATE=$(date +%F_%T)
 
TOMCAT_NAME=$1
TOMCAT_DIR=/usr/local/$TOMCAT_NAME
ROOT=$TOMCAT_DIR/webapps/ROOT
 
BACKUP_DIR=/data/backup
WORK_DIR=/tmp
PROJECT_NAME=tomcat-java-demo
 
# 拉取代码
cd $WORK_DIR
if [ ! -d $PROJECT_NAME ]; then
   git clone https://github.com/lizhenliang/tomcat-java-demo
   cd $PROJECT_NAME
else
   cd $PROJECT_NAME
   git pull
fi
 
# 构建
mvn clean package -Dmaven.test.skip=true
if [ $? -ne 0 ]; then
   echo "maven build failure!"
   exit 1
fi
 
# 部署
TOMCAT_PID=$(ps -ef |grep "$TOMCAT_NAME" |egrep -v "grep|$$" |awk 'NR==1{print $2}')
[ -n "$TOMCAT_PID" ] && kill -9 $TOMCAT_PID
[ -d $ROOT ] && mv $ROOT $BACKUP_DIR/${TOMCAT_NAME}_ROOT$DATE
unzip $WORK_DIR/$PROJECT_NAME/target/*.war -d $ROOT
$TOMCAT_DIR/bin/startup.sh
 
51.自动发布PHP项目  https://blog.csdn.net/heian_99/article/details/104062967
#!/bin/bash 
DATE=$(date +%F_%T) 
WWWROOT=/usr/local/nginx/html/$1 
BACKUP_DIR=/data/backup
WORK_DIR=/tmp
PROJECT_NAME=php-demo 
# 拉取代码
cd $WORK_DIR
if [ ! -d $PROJECT_NAME ]; then
   git clone https://github.com/lizhenliang/php-demo
   cd $PROJECT_NAME
else
   cd $PROJECT_NAME
   git pull
fi
 
 
# 部署
if [ ! -d $WWWROOT ]; then
   mkdir -p $WWWROOT
   rsync -avz --exclude=.git $WORK_DIR/$PROJECT_NAME/* $WWWROOT
else
   rsync -avz --exclude=.git $WORK_DIR/$PROJECT_NAME/* $WWWROOT
fi

53.目录入侵检测与告警  https://blog.csdn.net/heian_99/article/details/104063746
#!/bin/bash
#inotifywait、mail详解  https://blog.csdn.net/qq_43191116/article/details/109365820
#入侵就是看文件是否被更改过
MON_DIR=/opt
inotifywait -mqr --format %f -e create $MON_DIR |\
while read files; do
   #同步文件
   rsync -avz /opt /tmp/opt
  #检测文件是否被修改
   echo "$(date +'%F %T') create $files" | mail -s "dir monitor" [email protected]
done

54.本地选择脚本auto build.sh(https://www.bilibili.com/read/cv15257315)

55.服务器编译脚本 build.sh首先第一个使用的就是{$#}和($@)其次使用了字符串截取的操作

56.本地expect登陆拷贝scp exec.sh脚本(https://blog.csdn.net/weixin_43845433/article/details/120226699)
#!/bin/bash
expect -c "
  spawn scp -r src(源文件目录) [email protected]:dst(目标目录)
  expect {
    \"*assword*\" {
        set timeout 300; 
        send \"密码\r\";
        }
  }
expect eof"
————————————————
版权声明:本文为CSDN博主「迷茫期。。。」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43845433/article/details/120226699

57.检测两台服务器指定目录下的文件—致性(https://www.cnblogs.com/MR-ws/p/14884201.html)
#!/bin/bash
#####################################
#检测两台服务器指定目录下的文件一致性
#####################################
#通过对比两台服务器上文件的md5值,达到检测一致性的目的
dir=/data/web
b_ip=192.168.88.10
#将指定目录下的文件全部遍历出来并作为md5sum命令的参数,进而得到所有文件的md5值,并写入到指定文件中
find $dir -type f|xargs md5sum > /tmp/md5_a.txt
ssh $b_ip "find $dir -type f|xargs md5sum > /tmp/md5_b.txt"
scp $b_ip:/tmp/md5_b.txt /tmp
#将文件名作为遍历对象进行一一比对
for f in `awk '{print 2} /tmp/md5_a.txt'`
do
#以a机器为标准,当b机器不存在遍历对象中的文件时直接输出不存在的结果
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}'`
#当文件存在时,如果md5值不一致则输出文件改变的结果
if [ $md5_a != $md5_b ]
then
echo "$f changed."
fi
else
echo "$f deleted."
fi
done

58.定时清空文件内容,定时记录文件大小
https://blog.csdn.net/weibo1230123/category_10774666.html
https://blog.csdn.net/weibo1230123/article/details/115943728
#!/bin/bash
################################################################
#每小时执行一次脚本(任务计划),当时间为0点或12点时,将目标目录下的所有文件内
#容清空,但不删除文件,其他时间则只统计各个文件的大小,一个文件一行,输出到以时#间和日期命名的文件中,需要考虑目标目录下二级、三级等子目录的文件
################################################################
logfile=/tmp/`date +%H-%F`.log
n=`date +%H`
if [ $n -eq 00 ] || [ $n -eq 12 ]
then
#通过for循环,以find命令作为遍历条件,将目标目录下的所有文件进行遍历并做相应操作
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

59.检测网卡流量,并按规定格式记录在日志中  https://blog.csdn.net/weixin_44275820/article/details/116483907
#exec 
#!/bin/bash
#######################################################
#检测网卡流量,并按规定格式记录在日志中
#规定一分钟记录一次
#日志格式如下所示:
#2019-08-12 20:40
#ens33 input: 1234bps
#ens33 output: 1235bps
######################################################3
while :
do
#设置语言为英文,保障输出结果是英文,否则会出现bug
LANG=en
logfile=/tmp/`date +%d`.log
#将下面执行的命令结果输出重定向到logfile日志中
exec >> $logfile
date +"%F %H:%M"
#sar命令统计的流量单位为kb/s,日志格式为bps,因此要*1000*8
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 "####################"
#因为执行sar命令需要59秒,因此不需要sleep
done

60.计算文档每行出现的数字个数,并计算整个文档的数字总数  https://blog.csdn.net/weixin_44275820/article/details/116483907
#!/bin/bash
#seq、sed,seq详解  https://www.cnblogs.com/ftl1012/p/seq.html
#########################################################
#计算文档每行出现的数字个数,并计算整个文档的数字总数
########################################################
#使用awk只输出文档行数(截取第一段)
n=`wc -l a.txt|awk '{print $1}'`
sum=0
#文档中每一行可能存在空格,因此不能直接用文档内容进行遍历
for i in `seq 1 $n`
do
#输出的行用变量表示时,需要用双引号
line=`sed -n "$i"p a.txt`
#wc -L选项,统计最长行的长度,用sed+wc去统计每行中数字的个数,最终将每行的数字进行加和
n_n=`echo $line|sed s'/[^0-9]//'g|wc -L`
echo $n_n
sum=$[$sum+$n_n]
done
echo "sum:$sum"

61.从FTP服务器下载文件  https://blog.csdn.net/weixin_44275820/article/details/116483907
#!/bin/bash
if [ $# -ne 1 ]; then
    echo "Usage: $0 filename"
fi
dir=$(dirname $1)
file=$(basename $1)
ftp -n -v << EOF   # -n 自动登录
open 192.168.1.10  # ftp服务器
user admin password
binary   # 设置ftp传输模式为二进制,避免MD5值不同或.tar.gz压缩包格式错误
cd $dir
get "$file"
EOF

62.连续输入5个100以内的数字,统计和、最小和最大  https://blog.csdn.net/weixin_44275820/article/details/116483907
#!/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))
    #如下运用逻辑运算判断大小,也可以用if等判断,然后进行赋值,这个地方保留疑问?
    [ $MIN -lt $INT ] && MIN=$INT
    [ $MAX -gt $INT ] && MAX=$INT
    let COUNT++
done
echo "SUM: $SUM"
echo "MIN: $MIN"
echo "MAX: $MAX"

63.监测 Nginx 访问日志 502情况,并做相应动作  https://blog.csdn.net/weixin_44275820/article/details/116483907
场景:
#1.访问日志文件的路径:/data/log/access.log
#2.脚本死循环,每10秒检测一次,10秒的日志条数为300条,出现502的比例不低于10%(30条)则需要重启php-fpm服务
#3.重启命令为:/etc/init.d/php-fpm restart
#!/bin/bash
###########################################################
#监测Nginx访问日志502情况,并做相应动作
###########################################################
log=/data/log/access.log
N=30 #设定阈值
while :
do
 #查看访问日志的最新300条,并统计502的次数
    err=`tail -n 300 $log |grep -c '502" '`
 if [ $err -ge $N ]
 then
 /etc/init.d/php-fpm restart 2> /dev/null
 #设定60s延迟防止脚本bug导致无限重启php-fpm服务
     sleep 60
 fi
 sleep 10
done

64.将结果分别赋值给变量  https://blog.csdn.net/weixin_44275820/article/details/116483907
应用场景:希望将执行结果或者位置参数赋值给变量,以便后续使用。

方法1:

for i in $(echo "4 5 6"); do
   eval a$i=$i
done
echo $a4 $a5 $a6
方法2:将位置参数192.168.1.1{1,2}拆分为到每个变量

num=0
for i in $(eval echo $*);do   #eval将{1,2}分解为1 2
   let num+=1
   eval node${num}="$i"
done
echo $node1 $node2 $node3
# bash a.sh 192.168.1.1{1,2}
192.168.1.11 192.168.1.12
方法3:

arr=(4 5 6)
INDEX1=$(echo ${arr[0]})
INDEX2=$(echo ${arr[1]})
INDEX3=$(echo ${arr[2]})

65.批量修改文件名  https://blog.csdn.net/weixin_44275820/article/details/116483907
示例:

# touch article_{1..3}.html
# ls
article_1.html  article_2.html  article_3.html
目的:把article改为bbs

方法1:

for file in $(ls *html); do
    mv $file bbs_${file#*_}
    # mv $file $(echo $file |sed -r 's/.*(_.*)/bbs\1/')
    # mv $file $(echo $file |echo bbs_$(cut -d_ -f2)
done
方法2:

for file in $(find . -maxdepth 1 -name "*html"); do
     mv $file bbs_${file#*_}
done
方法3:

# rename article bbs *.html

66.统计当前目录中以html结尾的文件总大小  https://blog.csdn.net/weixin_44275820/article/details/116483907
方法1:
#du的使用方法
# find . -name "*.html" -exec du -k {} \; |awk '{sum+=$1}END{print sum}'

方法2:

for size in $(ls -l *.html |awk '{print $5}'); do
    sum=$(($sum+$size))
done
echo $sum

67.扫描主机端口状态  https://blog.csdn.net/weixin_44275820/article/details/116483907
#!/bin/bash
HOST=$1
PORT="22 25 80 8080"
for PORT in $PORT; do
    if echo &>/dev/null > /dev/tcp/$HOST/$PORT; then
        echo "$PORT open"
    else
        echo "$PORT close"
    fi
done

68.输入数字运行相应命令  https://blog.csdn.net/weixin_44275820/article/details/116483907
#!/bin/bash
##############################################################
#输入数字运行相应命令
##############################################################
echo "*cmd menu* 1-date 2-ls 3-who 4-pwd 0-exit "
while :
do
#捕获用户键入值
 read -p "please input number :" n
 n1=`echo $n|sed s'/[0-9]//'g`
#空输入检测 
 if [ -z "$n" ]
 then
 continue
 fi
#非数字输入检测 
 if [ -n "$n1" ]
 then
 exit 0
 fi
 break
done
case $n in
 1)
 date
 ;;
 2)
 ls
 ;;
 3)
 who
 ;;
 4)
 pwd
 ;;
 0)
 break
 ;;
    #输入数字非1-4的提示
 *)
 echo "please input number is [1-4]"
esac

69.Expect 实现 SSH 免交互执行命令  https://blog.csdn.net/weixin_44275820/article/details/116483907
Expect是一个自动交互式应用程序的工具,如telnet,ftp,passwd等。

需先安装expect软件包。

方法1:EOF标准输出作为expect标准输入

#!/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 "$1\r"}
expect "$USER@*"  {send "exit\r"}
expect eof
EOF
方法2:

#!/bin/bash
USER=root
PASS=123.com
IP=192.168.1.120
expect -c "
    spawn ssh $USER@$IP
    expect {
        \"(yes/no)\" {send \"yes\r\"; exp_continue}
        \"password:\" {send \"$PASS\r\"; exp_continue}
        \"$USER@*\" {send \"df -h\r exit\r\"; exp_continue}
    }"
方法3:将expect脚本独立出来

登录脚本:

# cat login.exp
#!/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"
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
执行命令脚本:写个循环可以批量操作多台服务器

#!/bin/bash
HOST_INFO=user_info.txt
for ip in $(awk '{print $1}' $HOST_INFO)
do
    user=$(awk -v I="$ip" 'I==$1{print $2}' $HOST_INFO)
    pass=$(awk -v I="$ip" 'I==$1{print $3}' $HOST_INFO)
    expect login.exp $ip $user $pass $1
done
Linux主机SSH连接信息:

# cat user_info.txt
192.168.1.120 root 123456

70.监控 httpd 的进程数,根据监控情况做相应处理  https://blog.csdn.net/weixin_44275820/article/details/116483907
#!/bin/bash
###############################################################################################################################
#需求:
#1.每隔10s监控httpd的进程数,若进程数大于等于500,则自动重启Apache服务,并检测服务是否重启成功
#2.若未成功则需要再次启动,若重启5次依旧没有成功,则向管理员发送告警邮件,并退出检测
#3.如果启动成功,则等待1分钟后再次检测httpd进程数,若进程数正常,则恢复正常检测(10s一次),否则放弃重启并向管理员发送告警邮件,并退出检测
###############################################################################################################################
#计数器函数
check_service()
{
 j=0
 for i in `seq 1 5` 
 do
 #重启Apache的命令
 /usr/local/apache2/bin/apachectl restart 2> /var/log/httpderr.log
    #判断服务是否重启成功
 if [ $? -eq 0 ]
 then
 break
 else
 j=$[$j+1]
 fi
    #判断服务是否已尝试重启5次
 if [ $j -eq 5 ]
 then
 mail.py
 exit
 fi
 done 
}
while :
do
 n=`pgrep -l httpd|wc -l`
 #判断httpd服务进程数是否超过500
 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`
 #判断重启后是否依旧超过500
             if [ $n2 -gt 500 ]
 then 
 mail.py
 exit
 fi
 fi
 fi
 #每隔10s检测一次
 sleep 10
done

71.批量修改服务器用户密码  https://blog.csdn.net/weixin_44275820/article/details/116483907
Linux主机SSH连接信息:旧密码

# cat old_pass.txt 
192.168.18.217  root    123456     22
192.168.18.218  root    123456     22
内容格式:IP User Password Port

SSH远程修改密码脚本:新密码随机生成
https://www.linuxprobe.com/books
#!/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 {
        \"(yes/no)\" {send \"yes\r\";exp_continue}
        \"password:\" {send \"$PASS\r\";exp_continue}
        \"$USER@*\" {send \"echo \'$NEW_PASS\' |passwd --stdin $USER\r exit\r\";exp_continue}
    }"
done
生成新密码文件:

# cat new_pass.txt 
192.168.18.217  root    n8wX3mU%      22
192.168.18.218  root    c87;ZnnL      22

72.iptables 自动屏蔽访问网站频须繁的IP  https://blog.csdn.net/weixin_44275820/article/details/116483907
场景:恶意访问,安全防范

1)屏蔽每分钟访问超过100的IP

方法1:根据访问日志(Nginx为例)

#!/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}')
#先tail防止文件过大,读取慢,数字可调整每分钟最大的访问量。awk不能直接过滤日志,因为包含特殊字符。
for IP in $ABNORMAL_IP; do
    if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then
        iptables -I INPUT -s $IP -j DROP
    fi
done
方法2:通过TCP建立的连接

#!/bin/bash
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
    fi
done

2)屏蔽每分钟SSH尝试登录超过10次的IP

方法1:通过lastb获取登录状态:

#!/bin/bash
DATE=$(date +"%a %b %e %H:%M") #星期月天时分  %e单数字时显示7,而%d显示07
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
    if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then
        iptables -I INPUT -s $IP -j DROP
    fi
done
方法2:通过日志获取登录状态

#!/bin/bash
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

73.根据web访问日志,封禁请求量异常的IP,如IP在半小时后恢复正常,则解除封禁  https://blog.csdn.net/weixin_44275820/article/details/116483907
https://blog.csdn.net/jj1130050965/article/details/116145253
#!/bin/bash
####################################################################################
#根据web访问日志,封禁请求量异常的IP,如IP在半小时后恢复正常,则解除封禁
####################################################################################
logfile=/data/log/access.log
#显示一分钟前的小时和分钟
d1=`date -d "-1 minute" +%H%M`
d2=`date +%M`
ipt=/sbin/iptables
ips=/tmp/ips.txt
block()
{
 #将一分钟前的日志全部过滤出来并提取IP以及统计访问次数
 grep '$d1:' $logfile|awk '{print $1}'|sort -n|uniq -c|sort -n > $ips
 #利用for循环将次数超过100的IP依次遍历出来并予以封禁
 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()
{
 #将封禁后所产生的pkts数量小于10的IP依次遍历予以解封
 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
}
#当时间在00分以及30分时执行解封函数
if [ $d2 -eq "00" ] || [ $d2 -eq "30" ]
 then
 #要先解再封,因为刚刚封禁时产生的pkts数量很少
 unblock
 block
 else
 block
fi
————————————————
版权声明:本文为CSDN博主「诸葛钢铁云」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jj1130050965/article/details/116145253

74.判断用户输入的是否为IP地址  https://blog.csdn.net/weixin_44275820/article/details/116483907
方法1:

#!/bin/bash
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.1
check_ip 256.1.1.1
方法2:

#!/bin/bash
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.1
check_ip 256.1.1.1
增加版:

加个死循环,如果IP可用就退出,不可用提示继续输入,并使用awk判断。

#!/bin/bash
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 || continue
done

76.轮询检测Apache状态并启用钉钉报警  https://www.cnblogs.com/Gxiaobai/p/14194329.html
#!/bin/sh
set -e
set -x
#
datapath=/opt/tmp/tomcat
# 这里定义发送的消息艾特多个人,
atMobiles=1538253****,1332273****
filecount=50
keyword="告警"
roomtext="Files have piled up Article"
 
dintalkurl="https://oapi.dingtalk.com/robot/send?access_token=3266108e7793b0ec704e9f60e84c9dd9c44c890f82ca04dc35f644c952deb859"
 
cnt=`ls -l ${datapath}/requestlogs/ | wc -l`
msg2="$ecs ${keyword}:[face] st ${roomtext} ${cnt}"
 
echo $msg2
 
if [ $cnt -gt $filecount ]; then
curl ${dintalkurl} \
 -H 'Content-Type: application/json' \
   -d '{"msgtype": "text",
        "text": {
             "content": "'"$msg2"'"
        },"at": {
                "atMobiles": ['${atMobiles}']
        }
      }'
fi

77.一台监控主机,一台被监控主机。被监控主机分区使用率大于80%,就发告警部邮件。放到crontab里面,每10分钟执行一次。https://www.cnblogs.com/fire909090/p/7573283.html
#!/bin/bash
              
                FSMAX="80"
                remote_user='root'
                remote_ip=(IP地址列表)
                 ip_num='0'
                while [ "$ip_num" -le "$(expr ${#remote_ip[@]} -l)"]
                do
                        read_num='1'
                        ssh "$remote_user"@"${remote_ip[$ip_num]}"  df -h > /tmp/diskcheck_tmp
                        grep '^/dev/*'  /tmp/diskcheck_tmp | awk '{print $5}'|sed 's/\%//g'  > /tmp/diskcheck_num_tmp
                    

                            while [ "$read_num" -le $(wc -l < /tmp/diskcheck_num_tmp) ]
                            do
                                    size=$(sed -n "$read_num" 'p'  /tmp/diskcheck_num_tmp)
                                            if [ "size" -gt "$FSMAX" ]
                                            then
                                                    $(grep '^/dev/*'  /tmp/diskcheck_tmp |sed -n $read_num'p'  > /tmp/disk_check_mail)
                                                    $(echo ${remote_ip[$ip_num]}) >> /tmp/disk_check_mail)
                                                    $(mail  -s "diskcheck_alert"  admin  <  /tmp/disk_check_mail)
                                            fi
                                    read_num=$(expr  $read_num + 1)
                            done
                        ip_num=$(expr  $ip_num + 1)
              done
              ===================写入crontab=====================
                0/10 * * * *   /home/diskcheck.sh   2&>1

78.监控主机的磁盘空间,当使用空间超过90%就通过发mail 来发警告  https://www.cnblogs.com/shxdyz/articles/7834265.html
#!/bin/bash
#cut的用法
#monitor available disk space

#提取本服务器的IP地址信息  
IP=`ifconfig eth0 | grep "inet addr" | cut -f 2 -d ":" | cut -f 1 -d " "`    
SPACE=` df -hP | awk '{print int($5)}'`
if [ $SPACE -ge 90 ]
then
echo "$IP 服务器 磁盘空间 使用率已经超过90%,请及时处理。"|mail -s "$IP 服务器硬盘告警"   [email protected]
fi

79.自动ftp上传  https://www.cnblogs.com/shxdyz/articles/7834265.html
#! /bin/bash
    ftp -n << END_FTP
    open 192.168.1.22
    user  test testing      //用户名test  密码:testing
    binary
    prompt  off    //关闭提示
    mput   files     //上传files文件
    close
    bye
    END_FTP
    
80.mysqlbak.sh备份数据库目录脚本  https://cloud.tencent.com/developer/article/1501150?from=15425
[root@localhost ~]# mysqldump -u operator -p123456 -h 192.168.1.1 --databases test1 > test1.sql
编写shell脚本:

[root@localhost ~]# mkdir -p /opt/backup             #创建备份后的存放目录
[root@localhost ~]# vim mysqlbak.sh                  #编写shell脚本

#!/bin/bash
#定义数据库连接、目标信息库等信息:
user="operator"       #定义用户名账号
pass="123456"        #密码
host="192.168.1.1"          #目标主机
conn=" -u $user -p$pass -h $host"
data1="test1"             #备份目标库
data2="test2"              
bak="/opt/backup"         #指定备份目录
cmd="/usr/local/mysql/bin/mysqldump"       #指定命令工具
time=`date +%Y%m%d-%H%M`             #定义时间变量
name_1="$data1-$time"                  #定义备份后的名字
name_2="$data2-$time"
cd $bak       #切换至备份目录下
$cmd $conn --databases $data1 > $name_1.sql            #备份为.sql文件
$cmd $conn --databases $data2 > $name_2.sql
/bin/tar zcf $name_1.tar.gz $name_1.sql --remove > /dev/null             #打包后删除源文件
/bin/tar zcf $name_2.tar.gz $name_2.sql --remove > /dev/null

81.打印彩虹  https://blog.csdn.net/Jasonliujintao/article/details/122941409
#!/bin/sh

#定义输出颜色的功能
rmsg() { echo -e "\033[31m$*\033[0m"; }
gmsg() { echo -e "\033[32m$*\033[0m"; }
bmsg() { echo -e "\033[34m$*\033[0m"; }

# 判断参数是否大于1个,如果没有参数就读入一个字符串作为参数
if [ $# -lt 1 ];then
    read -p "请输入字符串:" s
else
    s=$1
fi

# 判断如果输入的字符小于7个就输出一首诗
if [ ${#s} -lt 7 ];then
    rmsg "七绝.彩虹(平水韵)"
    gmsg "七绝.彩虹(平水韵)"
    bmsg "七绝.彩虹(平水韵)"
    s=`cat rainbow.txt`
fi

# 定义一个数组用来记录7中颜色的值
color=(31 32 33 34 35 36 37)

rainbow() {
    r=""  # 初始化原始输出字符串
    g=""  # 初始化背景色选择
    c=1  # 计算行数
    for ((i=0;i<${#s};i++))
    do
        n=`expr $i % 7` #取余数保持7种颜色
        if [ $n -eq 0 -a $i -gt 0 ];then  # 判断非第一行
        c=$(($c + 1))
            r=${r}"\n"
        fi
        if [ $c -eq 1 ];then  # 判断第一行
            g="4;"  # 设置下划线
        elif [ $c -eq 2 ];then
            g="7;"
    elif [ $c -eq 3 ];then
            g="1;2;"
        else
            g="5;"
        fi
        if [ $n -eq 2 ];then
       g=$g"44;"
    fi
    r=${r}"\033[${g}"${color[$n]}"m"${s:$i:1}"\033[0m"  # 拼接字符串
    done
    echo -e ${r}
}

# 调用rainbow 功能
rainbow
————————————————
版权声明:本文为CSDN博主「assless」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Jasonliujintao/article/details/122941409

82.打印菱形  https://blog.csdn.net/liuqingyuncsdn/article/details/109667378
#!/bin/bash
#打印菱形
read -p "please input the length:" line
for i in `seq 1 $line`
do
    for((j=$line;j>=i;j--))
    do
        echo -n " "
    done
    for((k=1;k<=i;k++))
    do
        echo -n "* "
    done
    echo
done
for i in `seq 1 $line`
do
    for((j=0;j<=$i;j++))
    do
        echo -n " "
    done
    for((k=$i;k<$line;k++))
    do
        echo -n "* "
    done
    echo
done


83.expect实现远程登陆自动交互  https://blog.csdn.net/qq_42761569/article/details/107690645
# 自动向传入的IP地址拷贝密钥的函数
copy_key () {
pwd='123'
# 开始 expect 解释器程序
/usr/bin/expect < # 设置捕获字符串后,期待回复的超时时间
set timeout 30
# 发送公钥给对方服务器
spawn ssh-copy-id root@$1
expect {
"yes/no" { send "yes\n"; exp_continue }
"password:" { send "${pwd}\n"} 
}
expect eof
EOF
}

host='Cloud'
# 循环把每个 Host 传递给自动拷贝函数
for i in {01..11}
do
   copy_key $host$i
done

84.http心跳检测  https://blog.csdn.net/devilcry13/article/details/82421307
#!/bin/bash
#设置变量,url为你需要检测的目标网站的网址(IP或域名)
url=http://192.168.4.5/index.html
 
#定义函数check_http:
#使用curl命令检查http服务器的状态
#-m设置curl不管访问成功或失败,最大消耗的时间为5秒,5秒连接服务为相应则视为无法连接
#-s设置静默连接,不显示连接时的连接速度、时间消耗等信息
#-o将curl下载的页面内容导出到/dev/null(默认会在屏幕显示页面内容)
#-w设置curl命令需要显示的内容%{http_code},指定curl返回服务器的状态码
check_http(){
status_code=$(curl -m 5 -s -o /dev/null -w %{http_code} $url)
}
 
while :
do
       check_http
       date=$(date +%Y%m%d-%H:%M:%S) 
#生成报警邮件的内容
       echo "当前时间为:$date
       $url服务器异常,状态码为${status_code}.
       请尽快排查异常." > /tmp/http$$.pid
       
#指定测试服务器状态的函数,并根据返回码决定是发送邮件报警还是将正常信息写入日志
       if [ $status_code -ne 200 ];then
              mail -s Warning root < /tmp/http$$.pid
       else
              echo "$url连接正常" >> /var/log/http.log
       fi
       sleep 5
done

85.PV过量自动实现防火墙封IP  https://www.bbsmax.com/A/A7zgKW7nz4/
#!/bin/bash
Info_File=/tmp/ddos_check.log
#awk的高级用法
#从连接数获取awk -F "[ :]+" '/180:80/{clsn[$6]++}
#netstat -lant|awk -F "[ :]+" '/180:80/{clsn[$6]++}END{for(pol in clsn)print pol,clsn[pol]}' >$Info_File

# 从日志获取
awk '{hotel[$1]++}END{for(pol in hotel)print pol,hotel[pol]}' access.log | sort -nk2 -r >$Info_File

while read line 
do 
   Ip_Add=`echo $line |awk '{print $1}'`
   Access=`echo $line |awk '{print $2}'`
   if [ $Access -ge 10000 ]; then
       iptables -I INPUT -s $Ip_Add -j DROP
   elif [ $Access -le 5000 ]; then
       echo "小于5000"
   else
       echo "大于5000小于10000"
   fi
done <$Info_File

86.shellI实现自动安装 https://blog.csdn.net/yaonianlong/article/details/41694677?utm_source=blogxgwz0
#!/bin/bash
 
//设置脚本中所需命令的执行路径
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
 
// $? 是取得上面执行命令的返回值,一般正确为0,错误为1
if [ "$?" != 0 ] ;
then
 //echo 为输出到屏幕
 echo "Please check your need software"
 //exit 0 为强制终止脚本
 exit 0
fi
 
 
// 声明回滚函数(作用是删除解压出来的文件)
rollback(){
   rm -rf apache-tomcat.tar.gz
   rm -rf MySQL-client-5.5.31-2.rhel5.i386.rpm
   rm -rf MySQL-server-5.5.31-2.rhel5.i386.rpm
   rm -rf jdk-6u29-linux-i586-rpm.bin
   rm -rf mysql.cnf
}
 
echo "Please choose to install or uninstall? (Installation: 1 / Uninstall: 0)"
 
//接收键盘输入,并把输入的值存放在userinput变量中
read userinput
 
//判断变量的值
if [ "$userinput" == '1' ] ;
then
 
//判断文件是否存在 
if [ ! -e medical.tar.gz ] ;
then
  echo "I cann't find medical.tar.gz file."
  exit 0
else
//存在则赋权并解压
chmod 755 medical.tar.gz
tar zxvf medical.tar.gz
fi
 
################################### Verify #################################
 
//判断本机是否安装了jdk
rpm -qa | grep jdk
if [ "$?" == 0 ] ;
then 
echo "Already installed JDK, please uninstall!"
rollback;
exit 0
fi 
 
//判断8080端口是否被占用
netstat -apn | grep 8080
if [ "$?" == 0 ] ;
then
echo "8080 port is occupied!"
rollback;
exit 0
fi
 
//判断本机是否安装了mysql
rpm -qa | grep -i mysql
if [ "$?" == 0 ] ;
then
echo "The system has been installed MySQL.Please run the uninstall!"
rollback;
exit 0
fi
 
//判断目录是否已存在
if [ -d /usr/tomcat-medical ] ; 
  then 

echo "/usr/tomcat-medical Directory exists"  
rollback; 
exit 0 
fi
 
//判断3306端口是否被占用
netstat -apn | grep 3306
if [ "$?" == 0 ] ;
then
echo "3306 port is occupied" 
rollback;
exit 0
fi
 
##################################### JDK ############################## # #
 
//赋权并安装jdk 
  chmod 755 jdk-6u29-linux-i586-rpm.bin 

./jdk-6u29-linux-i586-rpm.bin
//安装jdk的时候需要回车确认一下jdk的许可协议
 
######################################################################## #
 
//rpm包的jdk安装完成会自动生成 java/jdk**** 的文件夹,判断是否生成了jdk文件夹
if [ ! -d java/jdk1.6* ] ;
then
echo "I cann't find JDK directory."
rollback;
exit 0
fi
 
############################## Environment Variables ######################## #
 
//将一段文本追加到指定文件尾部(写入环境变量)
cat >> /etc/profile << EFF
 
JAVA_HOME=/usr/java/jdk1.6.0_29
JRE_HOME=\$JAVA_HOME/jre
CLASSPATH=:\$JAVA_HOME/lib:\$JRE_HOME/lib
PATH=\$JAVA_HOME:/bin:\$JRE_HOME/bin:\$PATH
export JAVA_HOME JRE_HOME CLASSPATH PATH
 
EFF
 //使环境变量立即生效
 source /etc/profile
 
#########################################################################
 
//判断环境变量是否已经生效
java -version
if [ "$?" != 0 ] ;
then
echo "I cann't set java path."
rollback;
exit 0
fi
 
####################### Delete JDK Installation file ######################## # # # # #
 
rm -rf jdk-6u29-linux-i586.rpm
rm -rf sun-javadb*
 
################################# MySQL ################################# #
 
//赋权并安装mysql
chmod 755 MySQL-server-5.5.31-2.rhel5.i386.rpm
rpm -ivh MySQL-server-5.5.31-2.rhel5.i386.rpm
 
################### Copy MySQL configuration file ########################### # # #
 
 //将一份已经准备好的配置文件替换mysql现有配置文件
 chmod 755 mysql.cnf
 cp mysql.cnf /usr/share/mysql/my-medium.cnf
 cp mysql.cnf /etc/my.cnf
 
 //启动或重启mysql
 netstat -apn | grep 3306
 if [ "$?" != 0 ] ;
 then
  service mysql start
 else
  service mysql restart
 fi
 
 //判断mysql是否启动成功
 netstat -apn | grep 3306
 if [ "$?" != 0 ] ;
 then
  echo "MySQL service failed to start!"
  rollback;
  exit 0
 fi
 
 //安装mysql用户端
 chmod 755 MySQL-client-5.5.31-2.rhel5.i386.rpm
 rpm -ivh MySQL-client-5.5.31-2.rhel5.i386.rpm
 
################################ Tomcat ##################################
 
 
 //赋权并解压tomcat
 chmod 755 apache-tomcat*.tar*
 tar zxvf apache-tomcat*.tar*
 mv apache-tomcat-6.0.32/ /usr/tomcat-medical/
       
################################ Medical ################################# #
 
 //赋权并解压应用到tomcat/webapps目录下
 chmod 755 medical.zip
 unzip medical.zip -d /usr/tomcat-medical/webapps/
 
 //判断当前目录下是否存在Install.zdt文件,存在则copy文件到指定目录下
 if [ -e Install.zdt ] ;
 then
   cp Install.zdt /usr/tomcat-medical/webapps/medical/WEB-INF/data/installer/
 fi
 
########################### Change Password ############################### #
 
 //等待5秒
 sleep 5
 //mysql默认密码为空,修改mysql密码(需要当前用户有mysql执行权限)
 mysqladmin flush-privileges password ' ******'
 
########################## Environment Variables ######################### # # # #
 
//环境变量
  cat >> /etc/profile << TTD 

  TOMCAT_HOME=/usr/tomcat-medical/ 

  PATH=\$PATH:\$TOMCAT_HOME/bin/:/usr/local/apache2/bin: 

  export JAVA_HOME JRE_HOME CLASSPATH PATH TOMCAT_HOME 

  TTD 

 
source /etc/profile
 
#########################################################################
 
 //启动tomcat
 sh /usr/tomcat-medical/bin/startup.sh
 
 //这里延迟5秒等待tomcat启动完成
 sleep 5
 
 //判断tomcat状态
 curl 127.0.0.1:8080 | grep "Thanks for using Tomcat"
 if [ "$?" != 0 ] ;
 then
  echo "I think install tomcat is unfinished ."
  rollback;
  exit 0
 fi
 
 rollback;
 
######################## Auto Start Up Services ############################ # # #
 
//把tomcat启动脚本加入rc.local文件中实现开机自动启动
cat >> /etc/rc.local << ASU
 
/usr/tomcat-medical/bin/startup.sh
 
ASU
 
 //设置mysql服务开机自动启动
 chkconfig --add mysql
 
########################################################################
 
//如果用户输入0的情况下执行卸载程序
elif [ "$userinput" == '0' ] ;
then
 
 echo "Uninstalling Tomcat......"
 
 netstat -apn | grep 8080
 if [ "$?" == 0 ] ;
 then
  sh /usr/tomcat-medical/bin/shutdown.sh
 fi
 
 rm -rf /usr/tomcat-medical/
 
 echo "Uninstalling JDK......"
 rpm -e jdk-1.6.0_29-fcs.i586
 
 echo "Uninstalling MySQL......"
 
 netstat -apn | grep 3306
 if [ "$?" == 0 ] ;
 then
  service mysql stop
 fi
 
 rpm -e MySQL-client-5.5.31-2.rhel5.i386
 rpm -e MySQL-server-5.5.31-2.rhel5.i386
 
 echo "Uninstall is complete please modify environment variables."
 
//如果用户输入的不是1或0则执行这里
else
 echo "You can only enter 1 or 0."
 
fi 
————————————————
版权声明:本文为CSDN博主「草原的风」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yaonianlong/article/details/41694677

87.shell实现插入排序  https://blog.csdn.net/jackeagle1/article/details/45919039
#!/bin/bash
a=(9 8 7 6 5 4 3 2 1 0)
for(( i=1; i<10; i++ ))
do
        for(( j=$i-1; j>=0; j-- ))
        do
                k=$[$j+1];
                if [ ${a[$k]} -lt ${a[$j]} ]
                then
                        temp=${a[$k]}
                        a[$k]=${a[$j]}
                        a[$j]=$temp
                fi
        done
done


for i in ${a[@]}
do
        echo -n "$i "
done
echo ""
————————————————
版权声明:本文为CSDN博主「jackeagle1」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jackeagle1/article/details/45919039

88.bash实现动态进度条  https://blog.csdn.net/Sudley/article/details/113918174
#!/bin/bash

mark=''
for ((ratio=0;${ratio}<=100;ratio+=5))
do
        sleep 0.2
        printf "progress:[%-40s]%d%%\r" "${mark}" "${ratio}"
        mark="##${mark}"
done
echo

89.根据文件内容创建账号  https://www.jianshu.com/p/eeb455eef7ca
#!/bin/bash
while read i
do
  user=`echo $i | awk '{print $1}'`
  pass=`echo $i | awk '{print $2}'`

  id $user || useradd $user
  echo $pass | passwd $user --stdin

done < test.list

90. 红色进度条  https://blog.csdn.net/baidu_37964071/article/details/80989559
[root@localhost ~]# cat jindutiao.sh
#!/bin/bash

num=0;
str=''
max=100
label=("|" "/" "-" "\\")
while [ $num -le $max ]
do
    ((color=30+num%8))
    echo -en "\e[1;"$color"m"
    printf "[\e[43;46;1m%-100s\e[0m][%d%%][%c]\r" "$str" "$num" "${label[num%4]}"
    let num++
    str=${str}'#'
    sleep 0.1
done
printf "\n"
echo -e "\e[1;30;m"

91.监控服务器网卡流量
https://blog.csdn.net/weixin_34380948/article/details/89582610
https://blog.csdn.net/weixin_36179941/article/details/116658787
#!/bin/bash
#用途:监控网卡流量的shell脚本。
#作者:Caron maktini
#日期:2018年11月23日
#版本:v0.1
#要求如下:每分钟检测一次网卡的流量;当网卡流量为0时,重启网卡。
 
[email protected] 
dir=/tmp/netlog
 
[ -d  Sdir ] II mkdir  $dir 
s_m=`lsattr -d  Sdir l awk ' {print $1} ' I  sed  's/[^a]//g'` 
if  [  $s_m  != "a" ]
then 
    chattr +a  $dir 
fi
 
if  ! rpm -q sysstat &> /dev/null 
then 
    yum install -y sysstat 
fi 
 
sar -n DEV 10 I grep 'eth0 ' > /tmp/eth0_sar. Iog 
net_in=`grep ' ^Average: ' /tmp/eth0_sar.log l awk '{ print $5}'` 
net_out=`grep ' ^Average: ' /tmp/eth0_sar.log l awk '{ print $6}'` 
 
 
if [ ! -f $dir/net.log ] 
then 
    echo"net_in $ net_in">> S dir/net. Iog 
    echo"net_out $ net_out">> S dir/net. Iog 
    exit 0
fi 
 
net_in_last=`tail-2  Sdir/net.Iog l grep 'net_in'` 
net_out_last=`tail-2  Sdir/net.Iog l grep 'net_out'` 
net_in_diff=`S [Snet_in-$net_in_last]`
net_out_diff=`S [S net_out-Snet_out_last]' 
if [  Snet_in_diff  -gt  $net_in_last ]
then 
      python mail.py $mail_user "网卡入口流量増幅异常" "增幅Snet_in_dff"       
fi 
if [ Snet_out_diff -gt Snet_out_last ] 
then 
      python mail.py $mail_user "网卡出口流量增幅异常" "增幅Snet_out_dff"      
fi 
echo  "net_in Snet_in" >> $ dir/net.Iog 
echo   "net_out  Snet_out">> $ dir/net.Iog 

92.检测CPU剩余百分比
#!/bin/bash
cpu_idle=`top -b -n 1 | grep cpu | awk '{print $5}' | cut -f 1 -d "."`
if (($cpu_idle < 20)); then 
  echo $CPU_idle
fi

93.检测磁盘剩余空间
df -k /media/Build/ | awk '{print int($5)}'

94.bash-实现检测apache状态并钉钉报警  https://www.cnblogs.com/pzyin/p/13947317.html
#! /bin/bash
 
count=$(less /usr/local/src/logs/info.log|grep 'RuntimeException:'|wc -l)
echo 'the count: ' $count
 
if (($count > 0));then
        echo 'send'
        source /home/script/ddSend.sh
fi
 
echo 'end'
95.内存检测

96.剩余inode检测

97.判断哪些用户登陆了系统
#!/bin/bash
#
user=`whoami`
if [ "$user" == "root" ];then
    echo "root is super user"
else
    echo "$user is a normal user"
fi

99.批量扫面存活  https://blog.51cto.com/xiaowangzai/2119515
#/bin/bash -
read -p "Please input scan host or network:" host
nmap -sn $host | grep "Nmap scan report for" >/dev/null &>/dev/null
[ $? -ne 0 ] && echo "host $host is down." && exit 1
nmap -sn $host  | grep "Nmap scan report for" | awk '{print $5}' > /scripts/host.txt
while read uphost
do
 echo "host $uphost is up."
done -----------------------------------
©著作权归作者所有:来自51CTO博客作者运维少年的原创作品,请联系作者获取转载授权,否则将追究法律责任
shell脚本案例(五)利用nmap批量扫描存活主机
https://blog.51cto.com/xiaowangzai/2119515

100.正则匹配IP
#!/bin/bash

ip="121.0.2.2"

if [[ $ip =~ ^([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0-9]{1,2}|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$ ]]

then

echo "Match"

echo ${BASH_REMATCH[1]}

echo ${BASH_REMATCH[2]}

echo ${BASH_REMATCH[3]}

echo ${BASH_REMATCH[4]}

else

echo "Not match"

fi
101.正则匹配邮箱
#! /bin/bash

function read_file(){undefined

for line in `cat $1`

do

if [ `echo $line |grep "^[a-zA-Z0-9_-]*@[A-Za-z_-]*\.[a-zA-Z_-]*$"` ];then

echo $line >> result.txt

else

echo "---" >> result.txt

fi

done

}

#eg

read_file a.txt
————————————————
版权声明:本文为CSDN博主「weixin_39786534」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_39786534/article/details/111806959

102.实现布片效果  https://www.cnblogs.com/LyShark/p/10221775.html
https://blog.csdn.net/weixin_30922589/article/details/95335063
#!/bin/bash
 
function ary_go
{
    $1 $2
    
    for (( i=0;i<=$1;i++ ))
    do
        for (( s=0;s<=$2;s++ ))
        do
            if [ $[$i%2] == 0 ]
            then
        
                if [ $[$s%2] == 0 ]
                then
                    echo -en "  "
                else
                    echo -en "\e[;44m  \e[;m"
                fi
            else
                                                if [ $[$s%2] == 0 ]
                                then
                                        echo -en "\e[;42m  \e[;m"
                                else
                                        echo -en "  "
                                fi
 
 
 
            fi
 
        done
            echo 
 
    done
 
}
 
ary_go 25 50

103.剔除白名单以外的用户  https://www.cnblogs.com/LyShark/p/10221775.html
#!/bin/bash
w | awk 'NR>=3 {printf $1 "\t" $2 "\t" $3 "\n"}' > /tmp/who.txt
for i in $(awk '{printf $1}' /tmp/bai.txt)
do
        k=$(egrep -v "$i" /tmp/who.txt | awk '{printf $2} "\n"' | awk '{printf $2 "\n"}')
        for j in $k
        do
                pkill -9 -t "$j"
        done
done

104.一键安装 MongoDB 数据库脚本  https://www.cnblogs.com/yhdsir/p/5026311.html
#!/bin/bash

# shell的执行选项:
# -n 只读取shell脚本,但不实际执行
# -x 进入跟踪方式,显示所执行的每一条命令
# -c "string" 从strings中读取命令

# 下载目录
downloadsDir=/root/Downloads
# 安装目录
appDir=/usr/local/mongodb

# 判断备份目录是否存在,不存时新建目录 
[ ! -d $downloadsDir ] && mkdir -p $downloadsDir
cd $downloadsDir

# 下载mongodb
curl -O http://downloads.mongodb.org/linux/mongodb-linux-x86_64-2.6.7.tgz
# 解压mongodb
tar -zxvf mongodb-linux-x86_64-2.6.7.tgz

rm -rf $appDir
mkdir -p $appDir

# 复制mongodb数据库文件到$appDir目录下
cp -R /root/Downloads/mongodb-linux-x86_64-2.6.7/* $appDir

mkdir -p $appDir/data/db
mkdir -p $appDir/log
mkdir -p $appDir/conf
mkdir -p $appDir/bin
chmod -R 777 $appDir

cd $appDir/conf
echo "################################ ZHAOXIACE DEFINE ##############################" >> mongod.conf
echo "port=27017  #指定服务端口号,默认端口27017" >> mongod.conf
echo "dbpath=data #指定数据库路径" >> mongod.conf
echo "logpath=log/mongod.log #指定MongoDB日志文件" >> mongod.conf
echo "auth=false #启用验证" >>mongod.conf
echo "fork=true #以守护进程的方式运行MongoDB,创建服务器进程" >> mongod.conf
cd ../

# 以修复模式启动
# ./bin/mongod -f conf/mongod.conf --repair

# 启动mongd服务
./bin/mongod -f conf/mongod.conf

# 连接数据库
./bin/mongo

105.使用mobaXtrem显示CentOS上的图形工具

106.一键申请多个证书 shell 脚本  https://blog.csdn.net/Dou_Hua_Hua/article/details/111267323
[root@centos8 ~]#cat certs.sh
#!/bin/bash
#
#********************************************************************
#Author:        wangxiaochun
#QQ:            29308620
#Date:          2020-02-29
#FileName:      test.sh
#URL:           http://www.wangxiaochun.com
#Description:       The test script
#Copyright (C):     2020 All rights reserved
#********************************************************************
. /etc/init.d/functions

CERT_INFO=([00]="/O=heaven/CN=ca.god.com" \
           [01]="cakey.pem" \
           [02]="cacert.pem" \
           [03]=2048 \
           [04]=3650 \
           [05]=0    \
           [10]="/C=CN/ST=hubei/L=wuhan/O=Central.Hospital/CN=master.liwenliang.org" \
           [11]="master.key" \
           [12]="master.crt" \
           [13]=2048 \
           [14]=365
           [15]=1 \
           [16]="master.csr" \
           [20]="/C=CN/ST=hubei/L=wuhan/O=Central.Hospital/CN=slave.liwenliang.org" \
           [21]="slave.key" \
           [22]="slave.crt" \
           [23]=2048 \
           [24]=365 \
           [25]=2 \
           [26]="slave.csr"   )

COLOR="echo -e \\E[1;32m"
END="\\E[0m"
DIR=/data
cd $DIR 

for i in {0..2};do
    if [ $i -eq 0 ] ;then
        openssl req  -x509 -newkey rsa:${CERT_INFO[${i}3]} -subj ${CERT_INFO[${i}0]} \
            -set_serial ${CERT_INFO[${i}5]} -keyout ${CERT_INFO[${i}1]} -nodes -days ${CERT_INFO[${i}4]} \
            -out ${CERT_INFO[${i}2]} &>/dev/null

    else 
        openssl req -newkey rsa:${CERT_INFO[${i}3]} -nodes -subj ${CERT_INFO[${i}0]} \
            -keyout ${CERT_INFO[${i}1]}   -out ${CERT_INFO[${i}6]} &>/dev/null

        openssl x509 -req -in ${CERT_INFO[${i}6]}  -CA ${CERT_INFO[02]} -CAkey ${CERT_INFO[01]}  \
            -set_serial ${CERT_INFO[${i}5]}  -days ${CERT_INFO[${i}4]} -out ${CERT_INFO[${i}2]} &>/dev/null
    fi
    $COLOR"**************************************生成证书信息**************************************"$END
    openssl x509 -in ${CERT_INFO[${i}2]} -noout -subject -dates -serial
    echo 
done
chmod 600 *.key
action "证书生成完成"

107.基于CentOS一键编译安装Redis脚本  https://www.cnblogs.com/weq0805/p/15302474.html
#!/bin/bash
#安装redis
read -p "请输入本机IP地址:" ip

systemctl stop firewalld
setenforce 0

#安装gcc gcc-c++ 编译器
yum install -y gcc gcc-c++ make &> /dev/null
if [ $? -eq 0 ];then
echo -e  "\033[34;1m 编译器安装完成! \033[0m"
fi

#将redis-5.0.7.tar.gz压缩包上传到/opt目录中,解压,并编译安装
cd /opt
tar zxvf redis-5.0.7.tar.gz -C /opt/ &> /dev/null
cd /opt/redis-5.0.7/
make &> /dev/null
make PREFIX=/usr/local/redis install &> /dev/null
if [ $? -eq 0 ];then
echo -e  "\033[34;1m redis编译安装完成! \033[0m"
fi

#执行软件包提供的installserver.sh脚本文件设置Redis服务所需要的相关配置文件
yum -y install expect &> /dev/null
/usr/bin/expect < cd /opt/redis-5.0.7/utils
spawn /opt/redis-5.0.7/utils/install_server.sh
expect "instance:" {send "\r"}
expect "/etc/redis/6379.conf" {send "\r"}
expect "/var/log/redis_6379.log" {send "\r"}
expect "/var/lib/redis/6379" {send "\r"}
expect "path" {send "/usr/local/redis/bin/redis-server\r"}
expect "ENTER" {send "\r"}
expect eof
EOF
if [ $? -eq 0 ];then
echo -e  "\033[34;1m redis相关配置完成! \033[0m"
fi

#把redis的可执行程序文件放入路径环境变量的目录中便于系统识别
ln -s /usr/local/redis/bin/* /usr/local/bin/
netstat -natp | grep redis

# Redis服务控制
/etc/init.d/redis_6379 start
/etc/init.d/redis_6379 status

#修改配置/etc/redis/6379.conf参数
sed -i '70s/bind 127.0.0.1/bind 127.0.0.1 '$ip'/' /etc/redis/6379.conf
/etc/init.d/redis_6379 restart
if [ $? -eq 0 ];then
echo -e  "\033[34;1m redis安装完成! \033[0m"
fi
netstat -natp | grep redis

108.基于CentOS一键安装tomcat脚本  https://blog.csdn.net/qq_33880971/article/details/54408735
#!/bin/sh
#自动安装脚本(包括包下载和环境配置)
mkdir -p /data/tomcat
path_top=/data/tomcat
#不要修改a的行号
a=0
#注意a是累加
let a+=1;
b=$a
sed -i -e "6c "a=$b"" tomcat_install.sh


##########################
cd $path_top
dir=tomcat$a
mkdir $dir
cd $dir
#内网下载
wget -c  http://192.168.0.220:8207/tomcat.tar.gz >/dev/null 2>&1

echo "tomcat download finish"
tar -zxf tomcat.tar.gz
rm -f tomcat.tar.gz


#安装jdk以及环境变量
a=`grep jar /etc/profile |awk -F. '{print $(4)}'`
if [[ $a = "jar" ]];then
echo "java install finish"
else
#内网下载
wget -c http://192.168.0.220:8207/jdk1.7.tar.gz >/dev/null 2>&1
tar -zxf jdk1.7.tar.gz
rm -f jdk1.7.tar.gz
cd ./jdk1.7.0_79/
echo "export JAVA_HOME=`pwd`" >> /etc/profile
echo "export PATH=\$JAVA_HOME/bin:\$PATH" >> /etc/profile
echo "export CLASSPATH=.:\$JAVA_HOME/lib/dt.jar:\$JAVA_HOME/lib/tools.jar" >> /etc/profile
`source /etc/profile`
source /etc/profile
echo "java environment is finished"
echo "java_pack=$path_top/$dir/jdk1.7.0_79"
echo "vironment can't immediate effect"
echo "Need to restart the client, or the input source/etc/profile"
fi


#修改server.xml文件的端口号
#shutdown端口
number01=810$b
sed -i -e "s|8005|"$number01"|" /$path_top/$dir/apache-tomcat-7.0.68/conf/server.xml
#访问端口
number02=820$b
sed -i -e "s|8080|"$number02"|" /$path_top/$dir/apache-tomcat-7.0.68/conf/server.xml
#AJP端口
number03=830$b
sed -i -e "s|8009|"$number03"|" /$path_top/$dir/apache-tomcat-7.0.68/conf/server.xml
echo "Tomcat has been installed"


echo "#############################"
echo "tomcat_path=$path_top/$dir"
echo "tomcat_prot=$number02"
echo "Please manually put the firewall release "$number02" port"

注意:

(1)a的值不要超过10

(2)开启tomcat之前先要运行source/etc/profile

(3)要注意文件名要与代码一致,或者修改代码
————————————————
版权声明:本文为CSDN博主「奋斗吧_小青年」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_33880971/article/details/54408735

109.一键证书申请和颁发脚本 https://www.cnblogs.com/tz66/p/13516128.html
#********************************************************************
#Author: zhangtianze
#QQ: 1185673631
#Date: 2020-08-07
#FileName: certificate.sh
#Copyright (C): 2020 All rights reserved
#********************************************************************
CA_SUBJECT="/O=heaven/CN=ca.god.com"
SUBJECT="/C=CN/ST=hubei/L=wuhan/O=Central.Hospital/CN=master.liwenliang.org"
SUBJECT2="/C=CN/ST=hubei/L=wuhan/O=Central.Hospital/CN=slave.liwenliang.org"
KEY_SIZE=2048 #此值不能使用1024
SERIAL=34
SERIAL2=35

CA_EXPIRE=202002
EXPIRE=365
FILE=master
FILE2=slave

#生成自签名的CA证书
openssl req -x509 -newkey rsa:${KEY_SIZE} -subj $CA_SUBJECT -keyout cakey.pem -nodes -days $CA_EXPIRE -out cacert.pem

#第一个证书
#生成私钥和证书申请
openssl req -newkey rsa:${KEY_SIZE} -nodes -keyout ${FILE}.key -subj $SUBJECT -out ${FILE}.csr
#颁发证书
openssl x509 -req -in ${FILE}.csr -CA cacert.pem -CAkey cakey.pem -set_serial $SERIAL -days $EXPIRE -out ${FILE}.crt

#第二个证书
openssl req -newkey rsa:${KEY_SIZE} -nodes -keyout ${FILE2}.key -subj $SUBJECT2 -out ${FILE2}.csr
openssl x509 -req -in ${FILE2}.csr -CA cacert.pem -CAkey cakey.pem -set_serial $SERIAL2 -days $EXPIRE -out ${FILE2}.crt

chmod 600 *.key

#####################################################################################################
1、编写hello world脚本

#!/bin/bash
 
# 编写hello world脚本
 
echo "Hello World!"
2、通过位置变量创建 Linux 系统账户及密码

#!/bin/bash
 
# 通过位置变量创建 Linux 系统账户及密码
 
#$1 是执行脚本的第一个参数,$2 是执行脚本的第二个参数
useradd    "$1" 
echo "$2"  |  passwd  ‐‐stdin  "$1"
3、备份日志

#!/bin/bash
# 每周 5 使用 tar 命令备份/var/log 下的所有日志文件
# vim  /root/logbak.sh
# 编写备份脚本,备份后的文件名包含日期标签,防止后面的备份将前面的备份数据覆盖
# 注意 date 命令需要使用反引号括起来,反引号在键盘键上面
tar    -czf    log-`date +%Y%m%d`.tar.gz    /var/log 
 
# crontab ‐e    #编写计划任务,执行备份脚本
00    03    *    *    5    /root/logbak.sh
4、一键部署 LNMP(RPM 包版本)

#!/bin/bash
# 一键部署 LNMP(RPM 包版本)
# 使用 yum 安装部署 LNMP,需要提前配置好 yum 源,否则该脚本会失败
# 本脚本使用于 centos7.2 或 RHEL7.2
yum ‐y install httpd
yum ‐y install mariadb mariadb‐devel mariadb‐server
yum ‐y install php  php‐mysql
 
systemctl start httpd mariadb
systemctl enable httpd mariadb
5、监控内存和磁盘容量,小于给定值时报警

#!/bin/bash
 
# 实时监控本机内存和硬盘剩余空间,剩余内存小于500M、根分区剩余空间小于1000M时,发送报警邮件给root管理员
 
# 提取根分区剩余空间
disk_size=$(df / | awk '/\//{print $4}')
 
# 提取内存剩余空间
mem_size=$(free | awk '/Mem/{print $4}')
while :
do
# 注意内存和磁盘提取的空间大小都是以 Kb 为单位
if  [  $disk_size -le 512000 -a $mem_size -le 1024000  ]
then
    mail  ‐s  "Warning"  root  <     Insufficient resources,资源不足
EOF
fi
done

6、猜数字游戏

 #!/bin/bash
 
# 脚本生成一个 100 以内的随机数,提示用户猜数字,根据用户的输入,提示用户猜对了,
# 猜小了或猜大了,直至用户猜对脚本结束。
 
# RANDOM 为系统自带的系统变量,值为 0‐32767的随机数
# 使用取余算法将随机数变为 1‐100 的随机数
num=$[RANDOM%100+1]
echo "$num"
 
# 使用 read 提示用户猜数字
# 使用 if 判断用户猜数字的大小关系:‐eq(等于),‐ne(不等于),‐gt(大于),‐ge(大于等于),
# ‐lt(小于),‐le(小于等于)
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

7、检测本机当前用户是否为超级管理员,如果是管理员,则使用 yum 安装 vsftpd,如果不是,则提示您非管理员(使用字串对比版本)

#!/bin/bash
 
# 检测本机当前用户是否为超级管理员,如果是管理员,则使用 yum 安装 vsftpd,如果不
# 是,则提示您非管理员(使用字串对比版本) 
if [ $USER == "root" ]
then
    yum ‐y install vsftpd
else
    echo "您不是管理员,没有权限安装软件"
fi
8、检测本机当前用户是否为超级管理员,如果是管理员,则使用 yum 安装 vsftpd,如果不是,则提示您非管理员(使用 UID 数字对比版本)

#!/bin/bash
 
# 检测本机当前用户是否为超级管理员,如果是管理员,则使用 yum 安装 vsftpd,如果不
# 是,则提示您非管理员(使用 UID 数字对比版本)
if [ $UID -eq 0 ];then
    yum ‐y install vsftpd
else
    echo "您不是管理员,没有权限安装软件"
fi
9、编写脚本:提示用户输入用户名和密码,脚本自动创建相应的账户及配置密码。如果用户不输入账户名,则提示必须输入账户名并退出脚本;如果用户不输入密码,则统一使用默认的 123456 作为默认密码。

#!/bin/bash
 
# 编写脚本:提示用户输入用户名和密码,脚本自动创建相应的账户及配置密码。如果用户
# 不输入账户名,则提示必须输入账户名并退出脚本;如果用户不输入密码,则统一使用默
# 认的 123456 作为默认密码。
 
read -p "请输入用户名: " user
#使用‐z 可以判断一个变量是否为空,如果为空,提示用户必须输入账户名,并退出脚本,退出码为 2
#没有输入用户名脚本退出后,使用$?查看的返回码为 2
if [ -z $user ];then
       echo "您不需输入账户名"
     exit 2
fi
#使用 stty ‐echo 关闭 shell 的回显功能
#使用 stty  echo 打开 shell 的回显功能
stty -echo
read -p "请输入密码: " pass
stty echo
pass=${pass:‐123456}
useradd "$user"
echo "$pass" | passwd ‐‐stdin "$user"

10、输入三个数并进行升序排序

#!/bin/bash
 
# 依次提示用户输入 3 个整数,脚本根据数字大小依次排序输出 3 个数字
read -p "请输入一个整数:" num1
read -p "请输入一个整数:" num2
read -p "请输入一个整数:" num3
# 不管谁大谁小,最后都打印 echo "$num1,$num2,$num3"
# num1 中永远存最小的值,num2 中永远存中间值,num3 永远存最大值
# 如果输入的不是这样的顺序,则改变数的存储顺序,如:可以将 num1 和 num2 的值对调
tmp=0
# 如果 num1 大于 num2,就把 num1 和和 num2 的值对调,确保 num1 变量中存的是最小值
if [ $num1 -gt $num2 ];then   
    tmp=$num1
    num1=$num2
    num2=$tmp
fi
# 如果 num1 大于 num3,就把 num1 和 num3 对调,确保 num1 变量中存的是最小值
if [ $num1 -gt $num3 ];then   
      tmp=$num1
      num1=$num3
      num3=$tmp
fi
# 如果 num2 大于 num3,就把 num2 和 num3 对标,确保 num2 变量中存的是小一点的值
if [ $num2 -gt $num3 ];then
      tmp=$num2
      num2=$num3
      num3=$tmp
fi
echo "排序后数据(从小到大)为:$num1,$num2,$num3"

11、石头、剪刀、布游戏

#!/bin/bash
 
# 编写脚本,实现人机<石头,剪刀,布>游戏
game=(石头 剪刀 布)
num=$[RANDOM%3]
computer=${game[$num]}
# 通过随机数获取计算机的出拳
# 出拳的可能性保存在一个数组中,game[0],game[1],game[2]分别是 3 中不同的可能
 
echo "请根据下列提示选择您的出拳手势"
echo "1.石头"
echo "2.剪刀"
echo "3.布"
 
read -p "请选择 1‐3:" person
case  $person  in
1)
  if [ $num -eq 0 ]
  then
    echo "平局"
    elif [ $num -eq 1 ]
    then
      echo "你赢"
  else
    echo "计算机赢"
  fi;;
2)   
  if [ $num -eq 0 ]
  then
    echo "计算机赢"
    elif [ $num -eq 1 ]
    then
      echo "平局"
  else
    echo "你赢"
  fi;;
3)
  if [ $num -eq 0 ]
  then
    echo "你赢"
    elif [ $num -eq 1 ]
    then
      echo "计算机赢"
  else
    echo "平局"
  fi;;
*)
  echo "必须输入 1‐3 的数字"
esac

12、编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,哪些主机处于关机状态(for 版本)

#!/bin/bash
 
# 编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,哪些主机处于关机
# 状态(for 版本)
for i in {1..254}
do
    # 每隔0.3秒ping一次,一共ping2次,并以1毫秒为单位设置ping的超时时间
       ping ‐c 2 ‐i 0.3 ‐W 1 192.168.4.$i  &>/dev/null
    if  [ $? -eq 0 ];then
           echo "192.168.4.$i is up"
       else
           echo  "192.168.4.$i is down"
       fi
done
13、编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,哪些主机处于关机状态(while 版本) 

#!/bin/bash
 
# 编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,哪些主机处于关机
# 状态(while 版本) 
i=1
while [ $i -le 254 ]
do
       ping ‐c 2 ‐i 0.3 ‐W 1 192.168.4.$i  &>/dev/null
       if  [ $? -eq 0 ];then
           echo "192.168.4.$i is up"
    else
           echo  "192.168.4.$i is down"
       fi
       let i++
done

14、编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,哪些主机处于关机状态(多进程版)

#!/bin/bash
 
# 编写脚本测试 192.168.4.0/24 整个网段中哪些主机处于开机状态,哪些主机处于关机
# 状态(多进程版)
 
#定义一个函数,ping 某一台主机,并检测主机的存活状态
myping(){
ping ‐c 2 ‐i 0.3 ‐W 1 $1  &>/dev/null
if  [ $? -eq 0 ];then
    echo "$1 is up"
else
    echo "$1 is down"
fi
}
for i in {1..254}
do
       myping 192.168.4.$i &
done
# 使用&符号,将执行的函数放入后台执行
# 这样做的好处是不需要等待ping第一台主机的回应,就可以继续并发ping第二台主机,依次类推。

15、编写脚本,显示进度条

#!/bin/bash
 
# 编写脚本,显示进度条
jindu(){
while :
do
       echo -n '#'
       sleep 0.2
done
}
jindu &
cp -a $1 $2
killall $0
echo "拷贝完成"
16、进度条,动态时针版本;定义一个显示进度的函数,屏幕快速显示|  / ‐ \

#!/bin/bash
 
# 进度条,动态时针版本
# 定义一个显示进度的函数,屏幕快速显示|  / ‐ \
rotate_line(){
INTERVAL=0.5  #设置间隔时间
COUNT="0"     #设置4个形状的编号,默认编号为 0(不代表任何图像)
while :
do
  COUNT=`expr $COUNT + 1` #执行循环,COUNT 每次循环加 1,(分别代表4种不同的形状)
  case $COUNT in          #判断 COUNT 的值,值不一样显示的形状就不一样
  "1")                    #值为 1 显示‐
          echo -e '‐'"\b\c"
          sleep $INTERVAL
          ;;
    "2")                  #值为 2 显示\\,第一个\是转义
          echo -e '\\'"\b\c"
          sleep $INTERVAL
          ;;
    "3")                  #值为 3 显示|
          echo -e "|\b\c"
          sleep $INTERVAL
          ;;
   "4")                   #值为 4 显示/
          echo -e "/\b\c"
          sleep $INTERVAL
          ;;
    *)                    #值为其他时,将 COUNT 重置为 0
          COUNT="0";;
    esac
done
}
rotate_line

17、9*9 乘法表

#!/bin/bash
 
# 9*9 乘法表(编写 shell 脚本,打印 9*9 乘法表) 
for i in `seq 9`
do
      for j in `seq $i`
       do
           echo -n "$j*$i=$[i*j]  "
       done
    echo
done
18、使用死循环实时显示 eth0 网卡发送的数据包流量

#!/bin/bash
 
# 使用死循环实时显示 eth0 网卡发送的数据包流量 
 
while :
do
     echo  '本地网卡 eth0 流量信息如下: '
      ifconfig eth0 | grep "RX pack" | awk '{print $5}'
    ifconfig eth0 | grep "TX pack" | awk '{print $5}'
       sleep 1
done
19、使用 user.txt 文件中的人员名单,在计算机中自动创建对应的账户并配置初始密码本脚本执行,需要提前准备一个 user.txt 文件,该文件中包含有若干用户名信息

#!/bin/bash
 
# 使用 user.txt 文件中的人员名单,在计算机中自动创建对应的账户并配置初始密码
# 本脚本执行,需要提前准备一个 user.txt 文件,该文件中包含有若干用户名信息
for i in `cat user.txt`
do
       useradd  $i
       echo "123456" | passwd ‐‐stdin $i
done
20、编写批量修改扩展名脚本

#!/bin/bash
 
# 编写批量修改扩展名脚本,如批量将 txt 文件修改为 doc 文件 
# 执行脚本时,需要给脚本添加位置参数
# 脚本名  txt  doc(可以将 txt 的扩展名修改为 doc)
# 脚本名  doc  jpg(可以将 doc 的扩展名修改为 jpg)
 
for i in `ls *.$1`
do
       mv $i ${i%.*}.$2
done
21、使用 expect 工具自动交互密码远程其他主机安装 httpd 软件

#!/bin/bash
 
# 使用 expect 工具自动交互密码远程其他主机安装 httpd 软件 
 
# 删除~/.ssh/known_hosts 后,ssh 远程任何主机都会询问是否确认要连接该主机
rm  ‐rf  ~/.ssh/known_hosts
expect < spawn ssh 192.168.4.254
expect "yes/no" {send "yes\r"}
# 根据自己的实际情况将密码修改为真实的密码字串
expect "password" {send  "密码\r"}
expect "#" {send  "yum ‐y install httpd\r"}
expect "#" {send  "exit\r"}
EOF

22、一键部署 LNMP(源码安装版本)

#!/bin/bash
 
# 一键部署 LNMP(源码安装版本)
menu()
{
clear
echo "  ##############‐‐‐‐Menu‐‐‐‐##############"
echo "# 1. Install Nginx"
echo "# 2. Install MySQL"
echo "# 3. Install PHP"
echo "# 4. Exit Program"
echo "  ########################################"
}
 
choice()
{
  read -p "Please choice a menu[1‐9]:" select
}
 
install_nginx()
{
  id nginx &>/dev/null
  if [ $? -ne 0 ];then
    useradd -s /sbin/nologin nginx
  fi
  if [ -f nginx‐1.8.0.tar.gz ];then
    tar -xf nginx‐1.8.0.tar.gz
    cd nginx‐1.8.0
    yum -y install  gcc pcre‐devel openssl‐devel zlib‐devel make
    ./configure ‐‐prefix=/usr/local/nginx ‐‐with‐http_ssl_module
    make
    make install
    ln -s /usr/local/nginx/sbin/nginx /usr/sbin/
    cd ..
  else
    echo "没有 Nginx 源码包"
  fi
}
 
install_mysql()
{
  yum -y install gcc gcc‐c++ cmake ncurses‐devel perl
  id mysql &>/dev/null
  if [ $? -ne 0 ];then
    useradd -s /sbin/nologin mysql
  fi
  if [ -f mysql‐5.6.25.tar.gz ];then
    tar -xf mysql‐5.6.25.tar.gz
    cd mysql‐5.6.25
    cmake .
    make
    make install
    /usr/local/mysql/scripts/mysql_install_db ‐‐user=mysql ‐‐datadir=/usr/local/mysql/data/
‐‐basedir=/usr/local/mysql/
    chown -R root.mysql /usr/local/mysql
    chown -R mysql /usr/local/mysql/data
    /bin/cp -f /usr/local/mysql/support‐files/mysql.server /etc/init.d/mysqld
    chmod +x /etc/init.d/mysqld
    /bin/cp -f /usr/local/mysql/support‐files/my‐default.cnf /etc/my.cnf
    echo "/usr/local/mysql/lib/" >> /etc/ld.so.conf
    ldconfig
    echo 'PATH=\$PATH:/usr/local/mysql/bin/' >> /etc/profile
    export PATH
  else
    echo  "没有 mysql 源码包"
    exit
  fi
}
 
install_php()
{
#安装 php 时没有指定启动哪些模块功能,如果的用户可以根据实际情况自行添加额外功能如‐‐with‐gd 等
yum  -y  install  gcc  libxml2‐devel
if [ -f mhash‐0.9.9.9.tar.gz ];then
  tar -xf mhash‐0.9.9.9.tar.gz
  cd mhash‐0.9.9.9
  ./configure
  make
  make install
  cd ..
if [ ! ‐f /usr/lib/libmhash.so ];then
  ln -s /usr/local/lib/libmhash.so /usr/lib/
fi
ldconfig
else
  echo "没有 mhash 源码包文件"
  exit
fi
if [ -f libmcrypt‐2.5.8.tar.gz ];then
  tar -xf libmcrypt‐2.5.8.tar.gz
  cd libmcrypt‐2.5.8
  ./configure
  make
  make install
  cd ..
  if [ ! -f /usr/lib/libmcrypt.so ];then  
    ln -s /usr/local/lib/libmcrypt.so /usr/lib/
  fi
  ldconfig
else
  echo "没有 libmcrypt 源码包文件"
  exit
fi
if [ -f php‐5.4.24.tar.gz ];then
  tar -xf php‐5.4.24.tar.gz
  cd php‐5.4.24
  ./configure  ‐‐prefix=/usr/local/php5  ‐‐with‐mysql=/usr/local/mysql  ‐‐enable‐fpm    ‐‐
  enable‐mbstring  ‐‐with‐mcrypt  ‐‐with‐mhash  ‐‐with‐config‐file‐path=/usr/local/php5/etc  ‐‐with‐
  mysqli=/usr/local/mysql/bin/mysql_config
  make && make install
  /bin/cp -f php.ini‐production /usr/local/php5/etc/php.ini
  /bin/cp -f /usr/local/php5/etc/php‐fpm.conf.default /usr/local/php5/etc/php‐fpm.conf
  cd ..
else
  echo "没有 php 源码包文件"
  exit
fi 
}
 
while :
do
  menu
  choice
  case $select in
  1)
    install_nginx
    ;;
  2)
    install_mysql
    ;;
  3)
    install_php
    ;;
  4)
    exit
    ;;
  *)
    echo Sorry!
  esac
done

23、编写脚本快速克隆 KVM 虚拟机

#!/bin/bash
 
# 编写脚本快速克隆 KVM 虚拟机
 
# 本脚本针对 RHEL7.2 或 Centos7.2
# 本脚本需要提前准备一个 qcow2 格式的虚拟机模板,
# 名称为/var/lib/libvirt/images  /.rh7_template 的虚拟机模板
# 该脚本使用 qemu‐img 命令快速创建快照虚拟机
# 脚本使用 sed 修改模板虚拟机的配置文件,将虚拟机名称、UUID、磁盘文件名、MAC 地址
# exit code:  
#    65 ‐> user input nothing
#    66 ‐> user input is not a number
#    67 ‐> user input out of range
#    68 ‐> vm disk image exists
 
IMG_DIR=/var/lib/libvirt/images
BASEVM=rh7_template
read -p "Enter VM number: " VMNUM
if [ $VMNUM -le 9 ];then
VMNUM=0$VMNUM
fi
 
if [ -z "${VMNUM}" ]; then
    echo "You must input a number."
    exit 65
elif [[  ${VMNUM} =~ [a‐z]  ]; then
    echo "You must input a number."
    exit 66
elif [ ${VMNUM} -lt 1 -o ${VMNUM} -gt 99 ]; then
    echo "Input out of range"
    exit 67
fi
 
NEWVM=rh7_node${VMNUM}
 
if [ -e $IMG_DIR/${NEWVM}.img ]; then
    echo "File exists."
    exit 68
fi
 
echo -en "Creating Virtual Machine disk image......\t"
qemu‐img create -f qcow2 ‐b $IMG_DIR/.${BASEVM}.img $IMG_DIR/${NEWVM}.img &> /dev/null
 
echo -e "\e[32;1m[OK]\e[0m"
 
#virsh dumpxml ${BASEVM} > /tmp/myvm.xml
cat /var/lib/libvirt/images/.rhel7.xml > /tmp/myvm.xml
sed -i "/${BASEVM}/s/${BASEVM}/${NEWVM}/" /tmp/myvm.xml
sed -i "/uuid/s/.*<\/uuid>/$(uuidgen)<\/uuid>/" /tmp/myvm.xml
sed -i "/${BASEVM}\.img/s/${BASEVM}/${NEWVM}/" /tmp/myvm.xml
 
# 修改 MAC 地址,本例使用的是常量,每位使用该脚本的用户需要根据实际情况修改这些值 
# 最好这里可以使用便利,这样更适合于批量操作,可以克隆更多虚拟机 
sed -i "/mac /s/a1/0c/" /tmp/myvm.xml
 
echo -en "Defining new virtual machine......\t\t"
virsh define /tmp/myvm.xml &> /dev/null
echo -e "\e[32;1m[OK]\e[0m"

24、点名器脚本

#!/bin/bash
 
# 编写一个点名器脚本
 
# 该脚本,需要提前准备一个 user.txt 文件
# 该文件中需要包含所有姓名的信息,一行一个姓名,脚本每次随机显示一个姓名
while :
do
#统计 user 文件中有多少用户
line=`cat user.txt |wc ‐l`
num=$[RANDOM%line+1]
sed -n "${num}p"  user.txt
sleep 0.2
clear
done

25、查看有多少远程的 IP 在连接本机

#!/bin/bash
 
# 查看有多少远程的 IP 在连接本机(不管是通过 ssh 还是 web 还是 ftp 都统计) 
 
# 使用 netstat ‐atn 可以查看本机所有连接的状态,‐a 查看所有,
# -t仅显示 tcp 连接的信息,‐n 数字格式显示
# Local Address(第四列是本机的 IP 和端口信息)
# Foreign Address(第五列是远程主机的 IP 和端口信息)
# 使用 awk 命令仅显示第 5 列数据,再显示第 1 列 IP 地址的信息
# sort 可以按数字大小排序,最后使用 uniq 将多余重复的删除,并统计重复的次数
netstat -atn  |  awk  '{print $5}'  | awk  '{print $1}' | sort -nr  |  uniq -c
26、对 100 以内的所有正整数相加求和(1+2+3+4...+100)

#!/bin/bash
 
# 对 100 以内的所有正整数相加求和(1+2+3+4...+100)
 
#seq 100 可以快速自动生成 100 个整数
sum=0
for i in `seq 100`
do
      sum=$[sum+i]
done
echo "总和是:$sum"
27、统计 13:30 到 14:30 所有访问 apache 服务器的请求有多少个

#!/bin/bash
 
# 统计 13:30 到 14:30 所有访问 apache 服务器的请求有多少个
 
# awk 使用‐F 选项指定文件内容的分隔符是/或者:
# 条件判断$7:$8 大于等于 13:30,并且要求,$7:$8 小于等于 14:30
# 最后使用 wc ‐l 统计这样的数据有多少行,即多少个
awk -F "[ /:]" '$7":"$8>="13:30" && $7":"$8<="14:30"' /var/log/httpd/access_log |wc -l
28、统计 13:30 到 14:30 所有访问本机 Aapche 服务器的远程 IP 地址是什么 

#!/bin/bash
 
# 统计 13:30 到 14:30 所有访问本机 Aapche 服务器的远程 IP 地址是什么 
# awk 使用‐F 选项指定文件内容的分隔符是/或者:
# 条件判断$7:$8 大于等于 13:30,并且要求,$7:$8 小于等于 14:30
# 日志文档内容里面,第 1 列是远程主机的 IP 地址,使用 awk 单独显示第 1 列即可
awk -F "[ /:]" '$7":"$8>="13:30" && $7":"$8<="14:30"{print $1}' /var/log/httpd/access_log
29、打印国际象棋棋盘

#!/bin/bash
 
# 打印国际象棋棋盘
# 设置两个变量,i 和 j,一个代表行,一个代表列,国际象棋为 8*8 棋盘
# i=1 是代表准备打印第一行棋盘,第 1 行棋盘有灰色和蓝色间隔输出,总共为 8 列
# i=1,j=1 代表第 1 行的第 1 列;i=2,j=3 代表第 2 行的第 3 列
# 棋盘的规律是 i+j 如果是偶数,就打印蓝色色块,如果是奇数就打印灰色色块
# 使用 echo ‐ne 打印色块,并且打印完成色块后不自动换行,在同一行继续输出其他色块
for i in {1..8}
do
      for j in {1..8}
      do
          sum=$[i+j]
        if [  $[sum%2] -eq 0 ];then
             echo -ne "\033[46m  \033[0m"
        else
            echo -ne "\033[47m  \033[0m"
        fi
      done
      echo
done

30、统计每个远程 IP 访问了本机 apache 几次?

#!/bin/bash
 
# 统计每个远程 IP 访问了本机 apache 几次? 
awk  '{ip[$1]++}END{for(i in ip){print ip[i],i}}'  /var/log/httpd/access_log
31、统计当前 Linux 系统中可以登录计算机的账户有多少个

#!/bin/bash
 
# 统计当前 Linux 系统中可以登录计算机的账户有多少个
#方法 1:
grep "bash$" /etc/passwd | wc -l
#方法 2:
awk -f: '/bash$/{x++}end{print x}'  /etc/passwd
32、统计/var/log 有多少个文件,并显示这些文件名

#!/bin/bash
 
# 统计/var/log 有多少个文件,并显示这些文件名 
# 使用 ls 递归显示所有,再判断是否为文件,如果是文件则计数器加 1
cd  /var/log
sum=0
for i in `ls -r *`
do
     if [ -f $i ];then
         let sum++
           echo "文件名:$i"
       fi
done
echo "总文件数量为:$sum"
33、自动为其他脚本添加解释器信息

#!/bin/bash
 
# 自动为其他脚本添加解释器信息#!/bin/bash,如脚本名为 test.sh 则效果如下: 
# ./test.sh  abc.sh    自动为 abc.sh 添加解释器信息
# ./test.sh  user.sh    自动为 user.sh 添加解释器信息
 
# 先使用 grep 判断对象脚本是否已经有解释器信息,如果没有则使用 sed 添加解释器以及描述信息
if  !  grep  -q  "^#!"  $1; then
sed  '1i #!/bin/bash'  $1
sed  '2i #Description: '
fi
# 因为每个脚本的功能不同,作用不同,所以在给对象脚本添加完解释器信息,以及 Description 后还希望
# 继续编辑具体的脚本功能的描述信息,这里直接使用 vim 把对象脚本打开,并且光标跳转到该文件的第 2 行
vim +2 $1
34、自动化部署 varnish 源码包软件

#!/bin/bash
 
# 自动化部署 varnish 源码包软件 
# 本脚本需要提前下载 varnish‐3.0.6.tar.gz 这样一个源码包软件,该脚本即可用自动源码安装部署软件
 
yum -y install gcc readline‐devel pcre‐devel
useradd -s /sbin/nologin varnish
tar -xf varnish‐3.0.6.tar.gz
cd varnish‐3.0.6
 
# 使用 configure,make,make install 源码安装软件包
./configure ‐‐prefix=/usr/local/varnish
make && make install
 
# 在源码包目录下,将相应的配置文件拷贝到 Linux 系统文件系统中
# 默认安装完成后,不会自动拷贝或安装配置文件到 Linux 系统,所以需要手动 cp 复制配置文件
# 并使用 uuidgen 生成一个随机密钥的配置文件
 
cp redhat/varnish.initrc /etc/init.d/varnish
cp redhat/varnish.sysconfig /etc/sysconfig/varnish
cp redhat/varnish_reload_vcl /usr/bin/
ln -s /usr/local/varnish/sbin/varnishd /usr/sbin/
ln -s /usr/local/varnish/bin/* /usr/bin
mkdir /etc/varnish
cp /usr/local/varnish/etc/varnish/default.vcl /etc/varnish/
uuidgen > /etc/varnish/secret

35、编写 nginx 启动脚本

#!/bin/bash
 
# 编写 nginx 启动脚本 
# 本脚本编写完成后,放置在/etc/init.d/目录下,就可以被 Linux 系统自动识别到该脚本
# 如果本脚本名为/etc/init.d/nginx,则 service nginx start 就可以启动该服务
# service nginx stop 就可以关闭服务
# service nginx restart 可以重启服务
# service nginx status 可以查看服务状态
 
program=/usr/local/nginx/sbin/nginx
pid=/usr/local/nginx/logs/nginx.pid
start(){
if [ -f $pid ];then
  echo  "nginx 服务已经处于开启状态"
else
  $program
fi
stop(){
if [ -! -f $pid ];then
  echo "nginx 服务已经关闭"
else
  $program -s stop
  echo "关闭服务 ok"
fi
}
status(){
if [ -f $pid ];then
  echo "服务正在运行..."
else
  echo "服务已经关闭"
fi
}
 
case $1 in
start)
  start;;
stop)
  stop;;
restart)
  stop
  sleep 1
  start;;
status)
  status;;
*)
  echo  "你输入的语法格式错误"
esac

36、自动对磁盘分区、格式化、挂载

 #!/bin/bash
 
# 自动对磁盘分区、格式化、挂载
# 对虚拟机的 vdb 磁盘进行分区格式化,使用<<将需要的分区指令导入给程序 fdisk
# n(新建分区),p(创建主分区),1(分区编号为 1),两个空白行(两个回车,相当于将整个磁盘分一个区)
# 注意:1 后面的两个回车(空白行)是必须的!
fdisk /dev/vdb << EOF
n
p
1
 
 
wq
EOF
 
#格式化刚刚创建好的分区
mkfs.xfs   /dev/vdb1
 
#创建挂载点目录
if [ -e /data ]; then
exit
fi
mkdir /data
 
#自动挂载刚刚创建的分区,并设置开机自动挂载该分区
echo '/dev/vdb1     /data    xfs    defaults        1 2'  >> /etc/fstab
mount -a

37、自动优化 Linux 内核参数

#!/bin/bash
 
# 自动优化 Linux 内核参数
 
#脚本针对 RHEL7
cat >> /usr/lib/sysctl.d/00‐system.conf < fs.file‐max=65535
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 5
net.ipv4.tcp_syn_retries = 5
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
#net.ipv4.tcp_keepalive_time = 120
net.ipv4.ip_local_port_range = 1024  65535
kernel.shmall = 2097152
kernel.shmmax = 2147483648
kernel.shmmni = 4096
kernel.sem = 5010 641280 5010 128
net.core.wmem_default=262144
net.core.wmem_max=262144
net.core.rmem_default=4194304
net.core.rmem_max=4194304
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_keepalive_time = 30
net.ipv4.tcp_window_scaling = 0
net.ipv4.tcp_sack = 0
EOF
 
sysctl –p

38、切割 Nginx 日志文件(防止单个文件过大,后期处理很困难)

#mkdir  /data/scripts
#vim   /data/scripts/nginx_log.sh  
#!/bin/bash
 
# 切割 Nginx 日志文件(防止单个文件过大,后期处理很困难) 
logs_path="/usr/local/nginx/logs/"
mv ${logs_path}access.log ${logs_path}access_$(date -d "yesterday" +"%Y%m%d").log
kill -USR1  `cat /usr/local/nginx/logs/nginx.pid`
 
# chmod +x  /data/scripts/nginx_log.sh
# crontab  ‐e                    #脚本写完后,将脚本放入计划任务每天执行一次脚本
0  1  *  *   *   /data/scripts/nginx_log.sh
39、检测 MySQL 数据库连接数量

#!/bin/bash
 
# 检测 MySQL 数据库连接数量 
 
# 本脚本每 2 秒检测一次 MySQL 并发连接数,可以将本脚本设置为开机启动脚本,或在特定时间段执行
# 以满足对 MySQL 数据库的监控需求,查看 MySQL 连接是否正常
# 本案例中的用户名和密码需要根据实际情况修改后方可使用
log_file=/var/log/mysql_count.log
user=root
passwd=123456
while :
do
    sleep 2
    count=`mysqladmin  -u  "$user"  -p  "$passwd"   status |  awk '{print $4}'`
    echo "`date +%Y‐%m‐%d` 并发连接数为:$count" >> $log_file
done

40、根据 md5 校验码,检测文件是否被修改

#!/bin/bash
 
# 根据 md5 校验码,检测文件是否被修改 
# 本示例脚本检测的是/etc 目录下所有的 conf 结尾的文件,根据实际情况,您可以修改为其他目录或文件
# 本脚本在目标数据没有被修改时执行一次,当怀疑数据被人篡改,再执行一次
# 将两次执行的结果做对比,MD5 码发生改变的文件,就是被人篡改的文件
for i in $(ls /etc/*.conf)
do
    md5sum "$i" >> /var/log/conf_file.log
done
41、检测 MySQL 服务是否存活

#!/bin/bash
 
# 检测 MySQL 服务是否存活 
 
# host 为你需要检测的 MySQL 主机的 IP 地址,user 为 MySQL 账户名,passwd 为密码
# 这些信息需要根据实际情况修改后方可使用
host=192.168.51.198
user=root
passwd=123456
mysqladmin -h '$host' -u '$user' -p'$passwd' ping &>/dev/null
if [ $? -eq 0 ]
then
        echo "MySQL is UP"
else
        echo "MySQL is down"
fi

42、备份 MySQL 的 shell 脚本(mysqldump版本)

#!/bin/bash
 
# 备份 MySQL 的 shell 脚本(mysqldump版本) 
 
# 定义变量 user(数据库用户名),passwd(数据库密码),date(备份的时间标签)
# dbname(需要备份的数据库名称,根据实际需求需要修改该变量的值,默认备份 mysql 数据库)
 
user=root
passwd=123456
dbname=mysql
date=$(date +%Y%m%d)
 
# 测试备份目录是否存在,不存在则自动创建该目录
[ ! -d /mysqlbackup ] && mkdir /mysqlbackup
# 使用 mysqldump 命令备份数据库
mysqldump -u "$user" -p "$passwd" "$dbname" > /mysqlbackup/"$dbname"-${date}.sql

43、将文件中所有的小写字母转换为大写字母

#!/bin/bash
 
# 将文件中所有的小写字母转换为大写字母 
 
# $1是位置参数,是你需要转换大小写字母的文件名称
# 执行脚本,给定一个文件名作为参数,脚本就会将该文件中所有的小写字母转换为大写字母
tr "[a‐z]" "[A‐Z]" < $1
44、非交互自动生成 SSH 密钥文件

#!/bin/bash
 
# 非交互自动生成 SSH 密钥文件 
 
# ‐t 指定 SSH 密钥的算法为 RSA 算法;‐N 设置密钥的密码为空;‐f 指定生成的密钥文件>存放在哪里
rm  -rf  ~/.ssh/{known_hosts,id_rsa*}
ssh‐keygen -t RSA -N '' -f ~/.ssh/id_rsa
45、检查特定的软件包是否已经安装

#!/bin/bash
 
# 检查特定的软件包是否已经安装 
if [ $# -eq 0 ];then
  echo "你需要制定一个软件包名称作为脚本参数"
  echo "用法:$0 软件包名称 ..."
fi
# $@提取所有的位置变量的值,相当于$*
for package in "$@"
do
      if rpm -q ${package} &>/dev/null ;then
        echo -e "${package}\033[32m 已经安装\033[0m"
      else
        echo -e "${package}\033[34;1m 未安装\033[0m"
      fi
done

46、监控 HTTP 服务器的状态(测试返回码)

#!/bin/bash
 
# 监控 HTTP 服务器的状态(测试返回码)
 
# 设置变量,url为你需要检测的目标网站的网址(IP 或域名),比如百度
url=http://http://183.232.231.172/index.html
 
# 定义函数 check_http:
# 使用 curl 命令检查 http 服务器的状态
# ‐m 设置curl不管访问成功或失败,最大消耗的时间为 5 秒,5 秒连接服务为相应则视为无法连接
# ‐s 设置静默连接,不显示连接时的连接速度、时间消耗等信息
# ‐o 将 curl 下载的页面内容导出到/dev/null(默认会在屏幕显示页面内容)
# ‐w 设置curl命令需要显示的内容%{http_code},指定curl返回服务器的状态码
check_http()
{
        status_code=$(curl -m 5 -s -o /dev/null -w %{http_code} $url)
}
 
while :
do
        check_http
        date=$(date +%Y%m%d‐%H:%M:%S)
 
# 生成报警邮件的内容
        echo "当前时间为:$date
        $url 服务器异常,状态码为${status_code}.
        请尽快排查异常." > /tmp/http$$.pid
 
# 指定测试服务器状态的函数,并根据返回码决定是发送邮件报警还是将正常信息写入日志
        if [ $status_code -ne 200 ];then
                mail -s Warning root < /tmp/http$$.pid
        else
                echo "$url 连接正常" >> /var/log/http.log
        fi
        sleep 5
done
 

47、自动添加防火墙规则,开启某些服务或端口(适用于 RHEL7)

#!/bin/bash
 
# 自动添加防火墙规则,开启某些服务或端口(适用于 RHEL7)

# 设置变量定义需要添加到防火墙规则的服务和端口号
# 使用 firewall‐cmd ‐‐get‐services 可以查看 firewall 支持哪些服务
service="nfs http ssh"
port="80 22 8080"
 
# 循环将每个服务添加到防火墙规则中
for i in $service
do
      echo "Adding $i service to firewall"
      firewall‐cmd  --add-service=${i}
done
 
#循环将每个端口添加到防火墙规则中
for i in $port
do
      echo "Adding $i Port to firewall"
      firewall‐cmd --add-port=${i}/tcp
done
#将以上设置的临时防火墙规则,转换为永久有效的规则(确保重启后有效)
firewall‐cmd  --runtime-to-permanent

48、使用脚本自动创建逻辑卷

#!/bin/bash
 
# 使用脚本自动创建逻辑卷 
 
# 清屏,显示警告信息,创建将磁盘转换为逻辑卷会删除数据
clear
echo -e "\033[32m           !!!!!!警告(Warning)!!!!!!\033[0m"
echo
echo "+++++++++++++++++++++++++++++++++++++++++++++++++"
echo "脚本会将整个磁盘转换为 PV,并删除磁盘上所有数据!!!"
echo "This Script will destroy all data on the Disk"
echo "+++++++++++++++++++++++++++++++++++++++++++++++++"
echo
read -p "请问是否继续 y/n?:" sure
 
# 测试用户输入的是否为 y,如果不是则退出脚本
[ $sure != y ] && exit
 
# 提示用户输入相关参数(磁盘、卷组名称等数据),并测试用户是否输入了这些值,如果没有输入,则脚本退出
read -p "请输入磁盘名称,如/dev/vdb:" disk
[ -z $disk ] && echo "没有输入磁盘名称" && exit
read -p "请输入卷组名称:" vg_name
[ -z $vg_name ] && echo "没有输入卷组名称" && exit
read -p "请输入逻辑卷名称:" lv_name
[ -z $lv_name ] && echo "没有输入逻辑卷名称" && exit
read -p "请输入逻辑卷大小:" lv_size
[ -z $lv_size ] && echo "没有输入逻辑卷大小" && exit
 
# 使用命令创建逻辑卷
pvcreate $disk
vgcreate $vg_name $disk
lvcreate -L ${lv_size}M -n ${lv_name}  ${vg_name}

49、显示 CPU 厂商信息

#!/bin/bash
 
# 显示 CPU 厂商信息 
awk '/vendor_id/{print $3}' /proc/cpuinfo | uniq
50、删除某个目录下大小为 0 的文件

#!/bin/bash
 
# 删除某个目录下大小为 0 的文件
 
#/var/www/html 为测试目录,脚本会清空该目录下所有 0 字节的文件
dir="/var/www/html"
find $dir -type f -size 0 -exec rm -rf {} \;
51、查找 Linux 系统中的僵尸进程

#!/bin/bash
 
# 查找 Linux 系统中的僵尸进程
 
# awk 判断 ps 命令输出的第 8 列为 Z 是,显示该进程的 PID 和进程命令
ps aux | awk '{if($8 == "Z"){print $2,$11}}'
52、提示用户输入年份后判断该年是否为闰年

#!/bin/bash
 
# 提示用户输入年份后判断该年是否为闰年
 
# 能被4整除并且并不能被100整除的年份是闰年
# 能被400整除的年份也是闰年
read -p "请输入一个年份:" year
 
if [ "$year" = "" ];then
    echo "没有输入年份"
    exit
fi
#使用正则测试变量 year 中是否包含大小写字母
if [[ "$year" =~ [a‐Z] ]];then
    echo "你输入的不是数字"
    exit
fi
# 判断是否为闰年
if [ $[year % 4] -eq 0 ] && [ $[year % 100] -ne 0 ];then
    echo "$year年是闰年"  
elif [ $[year % 400] -eq 0 ];then
    echo "$year年是闰年"
else
    echo "$year年不是闰年"
fi

53、生成随机密码(urandom 版本)

#!/bin/bash
 
# 生成随机密码(urandom 版本) 
 
# /dev/urandom 文件是 Linux 内置的随机设备文件
# cat /dev/urandom 可以看看里面的内容,ctrl+c 退出查看
# 查看该文件内容后,发现内容有些太随机,包括很多特殊符号,我们需要的密码不希望使用这些符号
# tr ‐dc '_A‐Za‐z0‐9' < /dev/urandom
# 该命令可以将随机文件中其他的字符删除,仅保留大小写字母,数字,下划线,但是内容还是太多
# 我们可以继续将优化好的内容通过管道传递给 head 命令,在大量数据中仅显示头 10 个字节
# 注意 A 前面有个下划线
tr -dc '_A‐Za‐z0‐9' 54、生成随机密码(字串截取版本)

#!/bin/bash
 
# 生成随机密码(字串截取版本) 
 
# 设置变量 key,存储密码的所有可能性(密码库),如果还需要其他字符请自行添加其他密码字符
# 使用$#统计密码库的长度
key="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
num=${#key}
# 设置初始密码为空
pass=''
# 循环 8 次,生成随机密码
# 每次都是随机数对密码库的长度取余,确保提取的密码字符不超过密码库的长度
# 每次循环提取一位随机密码,并将该随机密码追加到 pass 变量的最后
for i in {1..8}
do  
  index=$[RANDOM%num]
  pass=$pass${key:$index:1}
done
echo $pass

55、生成随机密码(UUID 版本,16 进制密码)

#!/bin/bash
 
# 生成随机密码(UUID 版本,16 进制密码) 
uuidgen
56、生成随机密码(进程 ID 版本,数字密码)

#!/bin/bash
 
# 生成随机密码(进程 ID 版本,数字密码)
echo $$
57、测试用户名与密码是否正确

#!/bin/bash
 
# 测试用户名与密码是否正确
 
#用户名为 tom 并且密码为 123456,则提示登录成功,否则提示登录失败
read -p "请输入用户名:"  user
read -p "请输入密码:"    pass
if [ "$user" == 'tom' -a "$pass" == '123456' ];then
    echo "Login successful"
else
    echo "Login Failed"
fi
58、循环测试用户名与密码是否正确

#!/bin/bash
 
# 循环测试用户名与密码是否正确 
 
# 循环测试用户的账户名和密码,最大测试 3 次,输入正确提示登录成功,否则提示登录失败
# 用户名为 tom 并且密码为 123456  
for i in {1..3}
do
    read -p "请输入用户名:" user
    read -p "请输入密码:"   pass
if [ "$user" == 'tom' -a "$pass" == '123456' ];then
      echo "Login successful"
       exit
fi
done
echo "Login Failed"

59、Shell 脚本的 fork 炸弹

#!/bin/bash
 
# Shell 脚本的 fork 炸弹 
 
# 快速消耗计算机资源,致使计算机死机
# 定义函数名为.(点), 函数中递归调用自己并放入后台执行
.() { .|.& };.
60、批量下载有序文件(pdf、图片、视频等等)

#!/bin/bash
 
# 批量下载有序文件(pdf、图片、视频等等)
 
# 本脚本准备有序的网络资料进行批量下载操作(如 01.jpg,02.jpg,03.jpg)
# 设置资源来源的域名连接
url="http://www.baidu.com/"
echo  "开始下载..."
sleep 2
type=jpg
for i in `seq 100`
       echo "正在下载$i.$type"
    curl $url/$i.$type -o /tmp/${i}$type
       sleep 1
done
#curl 使用-o 选项指定下载文件另存到哪里.

61、显示当前计算机中所有账户的用户名称

 #!/bin/bash
 
# 显示当前计算机中所有账户的用户名称
 
# 下面使用3种不同的方式列出计算机中所有账户的用户名
# 指定以:为分隔符,打印/etc/passwd 文件的第 1 列
awk -F: '{print $1}' /etc/passwd
 
# 指定以:为分隔符,打印/etc/passwd 文件的第 1 列
cut -d: -f1 /etc/passwd
 
# 使用 sed 的替换功能,将/etc/passwd 文件中:后面的所有内容替换为空(仅显示用户名)
sed 's/:.*//' /etc/passwd
62、制定目录路径,脚本自动将该目录使用 tar 命令打包备份到/data目录

#!/bin/bash
 
# 制定目录路径,脚本自动将该目录使用 tar 命令打包备份到/data目录 
 
[ ! -d /data ] && mkdir /data
[ -z $1 ] && exit
if [ -d $1 ];then
    tar -czf /data/$1.-`date +%Y%m%d`.tar.gz $1
else
      echo "该目录不存在"
fi
63、显示进度条(回旋镖版)

#!/bin/bash
 
# 显示进度条(回旋镖版)
 
while :
do
    clear
    for i in {1..20}
    do
        echo ‐e "\033[3;${i}H*"
        sleep 0.1
      done
      clear
      for i in {20..1}
      do
        echo ‐e "\033[3;${i}H*"
        sleep 0.1
      done
      clear
done

64、安装 LAMP 环境(yum 版本)

#!/bin/bash
 
# 安装 LAMP 环境(yum 版本) 
 
# 本脚本适用于 RHEL7(RHEL6 中数据库为 mysql)
yum makecache &>/dev/null
num=$(yum repolist | awk '/repolist/{print $2}' | sed 's/,//')
if [ $num -lt 0 ];then
    yum -y install httpd
    yum -y install mariadb mariadb-server mariadb-devel
    yum -y install php php-mysql
else
    echo "未配置 yum 源..."
fi
65、循环关闭局域网中所有主机

#!/bin/bash
 
# 循环关闭局域网中所有主机 
 
# 假设本机为 192.168.4.100,编写脚本关闭除自己外的其他所有主机
# 脚本执行,需要提前给所有其他主机传递 ssh 密钥,满足无密码连接
for i in {1..254}
do
    [ $i -eq 100 ] && continue
    echo "正在关闭 192.168.4.$i..."
    ssh 192.168.4.$i poweroff
done
66、获取本机 MAC 地址

#!/bin/bash
 
# 获取本机 MAC 地址
ip a s | awk 'BEGIN{print  " 本 机 MAC 地 址 信 息 如 下 :"}/^[0‐9]/{print $2;getline;if($0~/link\/ether/){print $2}}' | grep -v lo:
 
# awk 读取 ip 命令的输出,输出结果中如果有以数字开始的行,先显示该行的地 2 列(网卡名称),
# 接着使用 getline 再读取它的下一行数据,判断是否包含 link/ether
# 如果保护该关键词,就显示该行的第 2 列(MAC 地址)
# lo 回环设备没有 MAC,因此将其屏蔽,不显示
67、自动配置 rsynd 服务器的配置文件 rsyncd.conf

#!/bin/bash
 
# 自动配置 rsynd 服务器的配置文件 rsyncd.conf
 
# See rsyncd.conf man page for more options.
 
[ ! -d /home/ftp ] && mkdir /home/ftp
echo 'uid = nobody
gid = nobody
use chroot = yes
max connections = 4
pid file = /var/run/rsyncd.pid
exclude = lost+found/
transfer logging = yes
timeout = 900
ignore nonreadable = yes
dont compress   = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2
[ftp]
    path = /home/ftp
    comment = share' > /etc/rsyncd.conf

68、修改 Linux 系统的最大打开文件数量

#!/bin/bash
 
# 修改 Linux 系统的最大打开文件数量 
 
# 往/etc/security/limits.conf 文件的末尾追加两行配置参数,修改最大打开文件数量为 65536
cat >> /etc/security/limits.conf < * soft nofile  65536
* hard nofile  65536
EOF
69、设置 Python 支持自动命令补齐功能

#!/bin/bash
 
# 设置 Python 支持自动命令补齐功能 
 
# Summary:Enable tab complete for python
# Description:
 
Needs import readline and rlcompleter module
#
import readline
#
import rlcompleter
#
help(rlcompleter) display detail: readline.parse_and_bind('tab: complete')
#
man python display detail: PYTHONSTARTUP variable
 
if  [ ! -f /usr/bin/tab.py ];then
    cat >> /usr/bin/tab.py < import readline
import rlcompleter
readline.parse_and_bind('tab: complete')
EOF
fi
sed  -i '$a export PYTHONSTARTUP=/usr/bin/tab.py' /etc/profile
source /etc/profile

70、自动修改计划任务配置文件

#!/bin/bash
 
# 自动修改计划任务配置文件 
 
read -p "请输入分钟信息(00‐59):" min
read -p "请输入小时信息(00‐24):" hour
read -p "请输入日期信息(01‐31):" date
read -p "请输入月份信息(01‐12):" month
read -p "请输入星期信息(00‐06):" weak
read -p "请输入计划任务需要执行的命令或脚本:" program
echo "$min $hour $date $month $weak $program" >> /etc/crontab
71、使用脚本循环创建三位数字的文本文件(111-999 的文件)

#!/bin/bash
 
# 使用脚本循环创建三位数字的文本文件(111-999 的文件) 
 
for i in {1..9}
do
    for j in {1..9}
    do
        for k in {1..9}
        do
            touch /tmp/$i$j$k.txt
        done
      done
done
72、找出/etc/passwd 中能登录的用户,并将对应在/etc/shadow 中第二列密码提出处理

#!/bin/bash
 
# 找出/etc/passwd 中能登录的用户,并将对应在/etc/shadow 中第二列密码提出处理
 
user=$(awk -F: '/bash$/{print $1}' /etc/passwd)
for i in $user
do
    awk -F: -v x=$i '$1==x{print $1,$2}' /etc/shadow
done
73、统计/etc/passwd 中 root 出现的次数

#!/bin/bash
 
# 统计/etc/passwd 中 root 出现的次数 
 
#每读取一行文件内容,即从第 1 列循环到最后 1 列,依次判断是否包含 root 关键词,如果包含则 x++
awk -F: '{i=1;while(i<=NF){if($i~/root/){x++};i++}} END{print "root 出现次数为"x}' /etc/passwd
74、统计 Linux 进程相关数量信息

#!/bin/bash
 
# 统计 Linux 进程相关数量信息 
 
running=0
sleeping=0
stoped=0
zombie=0
# 在 proc 目录下所有以数字开始的都是当前计算机正在运行的进程的进程 PID
# 每个 PID 编号的目录下记录有该进程相关的信息
for pid in /proc/[1‐9]*
do
    procs=$[procs+1]
    stat=$(awk '{print $3}' $pid/stat)
# 每个 pid 目录下都有一个 stat 文件,该文件的第 3 列是该进程的状态信息
      case $stat in
      R)
        running=$[running+1]
        ;;
      T)
        stoped=$[stoped+1]
        ;;
      S)
        sleeping=$[sleeping+1]
        ;;
      Z)
         zombie=$[zombie+1]
         ;;
      esac
done
echo "进程统计信息如下"
echo "总进程数量为:$procs"
echo "Running 进程数为:$running"
echo "Stoped 进程数为:$stoped"
echo "Sleeping 进程数为:$sleeping"
echo "Zombie 进程数为:$zombie"

75、从键盘读取一个论坛积分,判断论坛用户等级

#!/bin/bash
 
# 从键盘读取一个论坛积分,判断论坛用户等级
 
#等级分类如下:
#  大于等于 90                神功绝世
#  大于等于 80,小于 90       登峰造极
#  大于等于 70,小于 80       炉火纯青
#  大于等于 60,小于 70       略有小成
#  小于 60                     初学乍练
read -p "请输入积分(0‐100):" JF
if [ $JF -ge 90 ] ; then
    echo "$JF 分,神功绝世"
elif [ $JF -ge 80 ] ; then
    echo "$JF 分,登峰造极"
elif [ $JF -ge 70 ] ; then
    echo "$JF 分,炉火纯青"
elif [ $JF -lt 60 ] ; then
    echo "$JF 分,略有小成"
else
    echo "$JF 分,初学乍练"
fi

76、判断用户输入的数据类型(字母、数字或其他) 

#!/bin/bash
 
# 判断用户输入的数据类型(字母、数字或其他) 
read -p "请输入一个字符:" KEY
case "$KEY" in
    [a‐z]|[A‐Z])
        echo "字母" 
        ;;
    [0‐9])
        echo "数字" 
        ;;
    *)
        echo "空格、功能键或其他控制字符"
esac
77、显示进度条(数字版) 

#!/bin/bash
 
# 显示进度条(数字版) 
# echo 使用‐e 选项后,在打印参数中可以指定 H,设置需要打印内容的 x,y 轴的定位坐标
# 设置需要打印内容在第几行,第几列
for i in {1..100}
do
      echo -e "\033[6;8H["
      echo -e "\033[6;9H$i%"
      echo -e "\033[6;13H]"
      sleep 0.1
done
78、打印斐波那契数列

#!/bin/bash
 
# 打印斐波那契数列(该数列的特点是后一个数字,永远都是前 2 个数字之和) 
 
# 斐波那契数列后一个数字永远是前 2 个数字之和
# 如:0  1  1  2  3  5  8  13 ... ...
list=(0 1)
for i in `seq 2 11`
do
    list[$i]=`expr ${list[‐1]} + ${list[‐2]}`
done
echo ${list[@]}
79、判断用户输入的是 Yes 或 NO

#!/bin/bash
 
# 判断用户输入的是 Yes 或 NO 
 
read -p  "Are you sure?[y/n]:"  sure
case  $sure  in
    y|Y|Yes|YES)  
        echo "you enter $a"
        ;;
    n|N|NO|no)
         echo "you enter $a"
         ;;
    *)
         echo "error";;
esac

80、显示本机 Linux 系统上所有开放的端口列表

#!/bin/bash
 
# 显示本机 Linux 系统上所有开放的端口列表 
 
# 从端口列表中观测有没有没用的端口,有的话可以将该端口对应的服务关闭,防止意外的攻击可能性
ss -nutlp | awk '{print $1,$5}' | awk -F"[: ]" '{print "协议:"$1,"端口号:"$NF}' | grep "[0‐9]" | uniq
81、将 Linux 系统中 UID 大于等于 1000 的普通用户都删除

#!/bin/bash
 
# 将 Linux 系统中 UID 大于等于 1000 的普通用户都删除 
 
# 先用 awk 提取所有 uid 大于等于 1000 的普通用户名称
# 再使用 for 循环逐个将每个用户删除即可
user=$(awk -F: '$3>=1000{print $1}' /etc/passwd)
for i in $user
do
       userdel -r $i
done
82、使用脚本开启关闭虚拟机

#!/bin/bash
 
# 使用脚本开启关闭虚拟机 
 
# 脚本通过调用virsh命令实现对虚拟机的管理,如果没有该命令,需要安装 libvirt‐client 软件包
# $1是脚本的第1个参数,$2是脚本的第2个参数
# 第1个参数是你希望对虚拟机进行的操作指令,第2个参数是虚拟机名称
case $1 in
  list)
    virsh list --all
    ;;
  start)
    virsh start $2
    ;;
  stop)
    virsh destroy $2
    ;;
  enable)
    virsh autostart $2
    ;;
  disable)
    virsh autostart --disable $2
    ;;
  *)
    echo "Usage:$0 list"
    echo "Usage:$0 [start|stop|enable|disable]  VM_name"
    cat << EOF
    #list      显示虚拟机列表
    #start     启动虚拟机
    #stop      关闭虚拟机
    #enable    设置虚拟机为开机自启
    #disable   关闭虚拟机开机自启功能
    EOF
    ;;
esac

83、调整虚拟机内存参数的 shell 脚本 

#!/bin/bash
 
# 调整虚拟机内存参数的 shell 脚本 
 
# 脚本通过调用 virsh 命令实现对虚拟机的管理,如果没有该命令,需要安装 libvirt‐client 软件包
cat << EOF
1.调整虚拟机最大内存数值
2.调整实际分配给虚拟机的内存数值
EOF
read -p "请选择[1‐2]:" select
case $select in
    1)
          read -p "请输入虚拟机名称" name
          read -p "请输入最大内存数值(单位:k):" size
          virsh setmaxmem $name --size $size --config
          ;;
    2)
          read -p "请输入虚拟机名称" name
          read -p "请输入实际分配内存数值(单位:k):" size
          virsh setmem $name $size
          ;;
    *)
          echo "Error"
          ;;
esac

84、查看 KVM 虚拟机中的网卡信息(不需要进入启动或进入虚拟机) 

#!/bin/bash
 
# 查看 KVM 虚拟机中的网卡信息(不需要进入启动或进入虚拟机) 
 
# 该脚本使用 guestmount 工具,可以将虚拟机的磁盘系统挂载到真实机文件系统中
# Centos7.2 中安装 libguestfs‐tools‐c 可以获得 guestmount 工具
# 虚拟机可以启动或者不启动都不影响该脚本的使用
# 将虚拟机磁盘文件挂载到文件系统后,就可以直接读取磁盘文件中的网卡配置文件中的数据
clear
mountpoint="/media/virtimage"
[ ! -d $mountpoint ] && mkdir $mountpoint
read -p "输入虚拟机名称:" name
echo "请稍后..."
# 如果有设备挂载到该挂载点,则先 umount 卸载
if mount | grep -q "$mountpoint" ;then
    umount $mountpoint
fi
# 只读的方式,将虚拟机的磁盘文件挂载到特定的目录下,这里是/media/virtimage 目录
guestmount -r -d $name -i $mountpoint
echo
echo "‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐"
echo -e "\033[32m$name 虚拟机中网卡列表如下:\033[0m"
dev=$(ls /media/virtimage/etc/sysconfig/network‐scripts/ifcfg-* |awk -F"[/‐]" '{print $9}')
echo $dev
echo "‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐"
echo
echo
echo "+++++++++++++++++++++++++++++++++++++++++++"
echo -e "\033[32m 网卡 IP 地址信息如下:\033[0m"
for i in $dev
do
  echo -n "$i:"
  grep -q "IPADDR" /media/virtimage/etc/sysconfig/network‐scripts/ifcfg-$i || echo "未配置 IP地址"
  awk -F= '/IPADDR/{print $2}' /media/virtimage/etc/sysconfig/network-scripts/ifcfg-$i
done
echo "+++++++++++++++++++++++++++++++++++++++++++"

85、不登陆虚拟机,修改虚拟机网卡 IP 地址

#!/bin/bash
 
# 不登陆虚拟机,修改虚拟机网卡 IP 地址 
 
# 该脚本使用 guestmount 工具,Centos7.2 中安装 libguestfs‐tools‐c 可以获得 guestmount 工具
# 脚本在不登陆虚拟机的情况下,修改虚拟机的 IP 地址信息
# 在某些环境下,虚拟机没有 IP 或 IP 地址与真实主机不在一个网段
# 真实主机在没有 virt‐manger 图形的情况下,远程连接虚拟机很麻烦
# 该脚本可以解决类似的问题
read -p "请输入虚拟机名称:" name
if virsh domstate $name | grep -q running ;then
    echo "修改虚拟机网卡数据,需要关闭虚拟机"
    virsh destroy $name
fi
mountpoint="/media/virtimage"
[ ! -d $mountpoint ] && mkdir $mountpoint
echo "请稍后..."
if mount | grep -q "$mountpoint" ;then
    umount $mountpoint
fi
guestmount  -d $name -i $mountpoint
read -p "请输入需要修改的网卡名称:" dev
read -p "请输入 IP 地址:" addr
# 判断原本网卡配置文件中是否有 IP 地址,有就修改该 IP,没有就添加一个新的 IP 地址
if grep -q "IPADDR"  $mountpoint/etc/sysconfig/network‐scripts/ifcfg‐$dev ;then
    sed -i "/IPADDR/s/=.*/=$addr/"  $mountpoint/etc/sysconfig/network‐scripts/ifcfg‐$dev
else
    echo "IPADDR=$addr" >> $mountpoint/etc/sysconfig/network‐scripts/ifcfg‐$dev
fi
# 如果网卡配置文件中有客户配置的 IP 地址,则脚本提示修改 IP 完成
awk -F= -v x=$addr '$2==x{print "完成..."}'  $mountpoint/etc/sysconfig/network‐scripts/ifcfg-$dev

86、破解虚拟机密码,无密码登陆虚拟机系统

#!/bin/bash
 
# 破解虚拟机密码,无密码登陆虚拟机系统 
 
# 该脚本使用 guestmount 工具,Centos7.2 中安装 libguestfs‐tools‐c 可以获得 guestmount 工具
 
read -p "请输入虚拟机名称:" name
if virsh domstate $name | grep -q running ;then
    echo "破解,需要关闭虚拟机"
    virsh destroy $name
fi
mountpoint="/media/virtimage"
[ ! -d $mountpoint ] && mkdir $mountpoint
echo "请稍后..."
if mount | grep -q "$mountpoint" ;then
    umount $mountpoint
fi
guestmount -d $name -i $mountpoint
# 将 passwd 中密码占位符号 x 删除,该账户即可实现无密码登陆系统
sed -i "/^root/s/x//" $mountpoint/etc/passwd

87、Shell 脚本对信号的处理,执行脚本后,按键盘 Ctrl+C 无法终止的脚本

#!/bin/bash
 
# Shell 脚本对信号的处理,执行脚本后,按键盘 Ctrl+C 无法终止的脚本 
 
# 使用 trap 命令可以拦截用户通过键盘或 kill 命令发送过来的信号
# 使用 kill ‐l 可以查看 Linux 系统中所有的信号列表,其中 2 代表 Ctrl+C
# trap 当发现有用户 ctrl+C 希望终端脚本时,就执行 echo "暂停 10s";sleep 10 这两条命令
# 另外用户使用命令:[ kill ‐2 脚本的 PID ] 也可以中断脚本和 Ctrl+C 一样的效果,都会被 trap 拦截
trap 'echo "暂停 10s";sleep 10' 2
while :
do
    echo "go go go"
done
88、一键部署 memcached

#!/bin/bash
 
# 一键部署 memcached 
 
# 脚本用源码来安装 memcached 服务器
# 注意:如果软件的下载链接过期了,请更新 memcached 的下载链接
wget http://www.memcached.org/files/memcached-1.5.1.tar.gz
yum -y install gcc
tar -xf  memcached‐1.5.1.tar.gz
cd memcached‐1.5.1
./configure
make
make install
89、一键配置 VNC 远程桌面服务器(无密码版本)

#!/bin/bash
 
# 一键配置 VNC 远程桌面服务器(无密码版本)
 
# 脚本配置的 VNC 服务器,客户端无需密码即可连接
# 客户端仅有查看远程桌面的权限,没有鼠标和键盘的操作权限
 
rpm --quiet -q tigervnc‐server
if [  $? -ne  0 ];then
    yum  -y  tigervnc‐server
fi
x0vncserver AcceptKeyEvents=0 AlwaysShared=1 \
AcceptPointerEvents=0 SecurityTypes=None  rfbport=5908
90、关闭 SELinux

#!/bin/bash
 
# 关闭 SELinux 
 
sed -i  '/^SELINUX/s/=.*/=disabled/' /etc/selinux/config
setenforce 0
91、查看所有虚拟机磁盘使用量以及CPU使用量信息

#!/bin/bash
 
# 查看所有虚拟机磁盘使用量以及CPU使用量信息 
 
virt‐df
read -n1 "按任意键继续" key
virt‐top
92、使用 shell 脚本打印图形

#!/bin/bash
 
# 使用 shell 脚本打印如下图形: 
 
# 打印第一组图片
# for(())为类 C 语言的语法格式,也可以使用 for i  in;do  ;done 的格式替换
# for((i=1;i<=9;i++))循环会执行 9 次,i 从 1 开始到 9,每循环一次 i 自加 1
clear
for (( i=1; i<=9; i++ ))
do
  for (( j=1; j<=i; j++ ))
  do
    echo -n "$i"
  done
  echo ""
done
read  -n1  "按任意键继续"  key
#打印第二组图片
clear
for (( i=1; i<=5; i++ )) 
do
  for (( j=1; j<=i; j++ ))
  do
    echo -n " |"
  done
  echo "_ "
done
read  -n1  "按任意键继续"  key
#打印第三组图片
clear
for (( i=1; i<=5; i++ ))
do
  for (( j=1; j<=i; j++ ))
  do
    echo -n " *"
  done
  echo ""
done
for (( i=5; i>=1; i‐‐ ))
do
  for (( j=1; j<=i; j++ ))
  do
    echo -n " *"
  done
  echo ""
done

93、根据计算机当前时间,返回问候语,可以将该脚本设置为开机启动

#!/bin/bash
 
# 根据计算机当前时间,返回问候语,可以将该脚本设置为开机启动 
 
# 00‐12 点为早晨,12‐18 点为下午,18‐24 点为晚上
# 使用 date 命令获取时间后,if 判断时间的区间,确定问候语内容
tm=$(date +%H)
if [ $tm -le 12 ];then
    msg="Good Morning $USER"
elif [ $tm -gt 12 -a $tm -le 18 ];then
      msg="Good Afternoon $USER"
else
      msg="Good Night $USER"
fi
echo "当前时间是:$(date +"%Y‐%m‐%d %H:%M:%S")"
echo -e "\033[34m$msg\033[0m"

94、读取用户输入的账户名称,将账户名写入到数组保存

#!/bin/bash
 
# 读取用户输入的账户名称,将账户名写入到数组保存 
 
# 定义数组名称为 name,数组的下标为 i,小标从 0 开始,每输入一个账户名,下标加 1,继续存下一个账户
# 最后,输入 over,脚本输出总结性信息后脚本退出
i=0
while :
do
    read -p "请输入账户名,输入 over 结束:" key
    if [ $key == "over" ];then 
        break
      else
        name[$i]=$key
        let i++
      fi
done
echo "总账户名数量:${#name[*]}"
echo "${name[@]}"

95、判断文件或目录是否存在

#!/bin/bash
 
# 判断文件或目录是否存在 
 
if [ $# -eq 0 ] ;then
echo "未输入任何参数,请输入参数"
echo "用法:$0 [文件名|目录名]"
fi
if [ -f $1 ];then
    echo "该文件,存在"
    ls -l $1
else
    echo "没有该文件"
fi
if [ -d  $1 ];then
       echo "该目录,存在"
       ls -ld  $2
else
       echo "没有该目录"
fi

96、打印各种格式的时间

#!/bin/bash
 
# 打印各种时间格式 
 
echo "显示星期简称(如:Sun)"
date +%a
echo "显示星期全称(如:Sunday)"
date +%A
echo "显示月份简称(如:Jan)"
date +%b
echo "显示月份全称(如:January)"
date +%B
echo "显示数字月份(如:12)"
date +%m
echo "显示数字日期(如:01 号)"
date +%d
echo "显示数字年(如:01 号)"
date +%Y echo "显示年‐月‐日"
date +%F
echo "显示小时(24 小时制)"
date +%H
echo "显示分钟(00..59)"
date +%M
echo "显示秒"
date +%S
echo "显示纳秒"
date +%N
echo "组合显示"
date +"%Y%m%d %H:%M:%S"

97、使用 egrep 过滤 MAC 地址

#!/bin/bash
 
# 使用 egrep 过滤 MAC 地址 
 
# MAC 地址由 16 进制组成,如 AA:BB:CC:DD:EE:FF
# [0‐9a‐fA‐F]{2}表示一段十六进制数值,{5}表示连续出现5组前置:的十六进制
egrep "[0‐9a‐fA‐F]{2}(:[0‐9a‐fA‐F]{2}){5}" $1
98、统计双色球各个数字的中奖概率

#!/bin/bash
 
# 统计双色球各个数字的中奖概率 
 
# 往期双色球中奖号码如下:
# 01 04 11 28 31 32  16
# 04 07 08 18 23 24  02
# 02 05 06 16 28 29  04
# 04 19 22 27 30 33  01
# 05 10 18 19 30 31  03
# 02 06 11 12 19 29  06
# 统计篮球和红球数据出现的概率次数(篮球不分顺序,统计所有篮球混合在一起的概率)
awk '{print $1"\n"$2"\n"$3"\n"$4"\n"$5"\n"$6}' 1.txt | sort | uniq -c | sort
awk '{print $7}' 1.txt | sort | uniq -c | sort
99、生成签名私钥和证书

#!/bin/bash
 
# 生成签名私钥和证书 
 
read -p "请输入存放证书的目录:" dir
if [ ! -d $dir ];then
    echo "该目录不存在"
    exit
fi
read -p "请输入密钥名称:" name
# 使用 openssl 生成私钥
openssl genrsa -out ${dir}/${name}.key
# 使用 openssl 生成证书 #subj 选项可以在生成证书时,非交互自动填写 Common Name 信息
openssl req -new -x509 -key ${dir}/${name}.key -subj "/CN=common" -out ${dir}/${name}.crt
100、使用awk编写的wc程序

#!/bin/bash
 
# 使用awk编写的wc程序 
 
# 自定义变量 chars 变量存储字符个数,自定义变量 words 变量存储单词个数
# awk 内置变量 NR 存储行数
# length()为 awk 内置函数,用来统计每行的字符数量,因为每行都会有一个隐藏的$,所以每次统计后都+1
# wc 程序会把文件结尾符$也统计在内,可以使用 cat ‐A 文件名,查看该隐藏字符
awk '{chars+=length($0)+1;words+=NF} END{print NR,words,chars}' $1
————————————————
版权声明:本文为CSDN博主「baiduoWang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yugemengjing/article/details/82469785
 

你可能感兴趣的:(Linux,解决方案,面试,linux,职场和发展)