Linux运维:shell脚本(3)

总结一下并记录碰到的shell脚本,持续更新.......

系列笔记传送门:

1、统计进程占用内存大小

写一个脚本计算一下linux系统所有进程占用内存大小的和。

#!/bin/bash
sum=0
for mem in `ps aux | awk '{print $6}' | grep -v 'RSS'`
do
    sum=$[$sum + $mem]
done
echo "The total memory is $sum"

2、批量创建用户

写一个脚本实现:
添加user_00-user-09总共10个用户,并且对这10个用户设置一个随机密码,密码要求10位包含大小写字母以及数字,最后将每个用户的密码记录到一个日志文件里。

#!/bin/bash
for i in `seq -w 0 09`
do
    useradd user_$i
    p=`mkpasswd -s 0 -l 10`
    echo "user_$i $p" >> /tmp/user0_9.pass
    echo $p |passwd --stdin user_$i
done

3、URL检测脚本

编写shell脚本检测URL是否正常。

#!/bin/bash
. /etc/init.d/functions

function usage(){
    echo $"usage:$0 url"
    exit 1
}

function check_url(){
    wget --spider -q -o /dev/null --tries=1 -T 5 $1
    if [ $? -eq 0 ];then
        action "$1 is yes." /bin/true
    else
        action "$1 is no." /bin/false
    fi
}

function main(){
    if [ $# -ne 1 ];then
        usage
    fi
    check_url $1
}
main $*

测试结果:

[root@moli_linux1 script]# sh check_url.sh www.baidu.com
www.baidu.com is yes.                                      [  确定  ]
[root@moli_linux1 script]# sh check_url.sh www.baiduxxx.com
www.baiduxxx.com is no.                                    [失败]

4、结合while循环,每隔10s检查多个网站是否正常

#!/bin/bash
. /etc/init.d/functions
check_count=0
url_list=(            # 定义URL数组,可以写多个URL
https://www.baidu.com
https://www.qq.com
https://segmentfault.com
)

function wait(){        # 定义倒计时函数
    echo -n '3秒后,执行检查URL操作.'
    for ((i=0;i<3;i++))
    do
        echo -n ".";sleep 1 
    done
    echo 
}
function check_url(){  # 定义检测函数
    wait
    for ((i=0;i<`echo ${#url_list[*]}`;i++))
    do
        # wget这条命令检测数组里面的URL地址能否被正常访问,正常访问返回0,访问失败返回非0数字
        wget -o /dev/null -T 3 --tries=1 --spider ${url_list[$i]} > /dev/null 2>&1
     if [ $? -eq 0 ];then    # $?返回值为0表示网址正常
            action "${url_list[$i]}" /bin/true
        else 
            action "${url_list[$i]}" /bin/false
        fi
    done
    ((check_count++))
}
function main(){
    while true
    do
     check_url
    echo "---------check count:${check_count}---------"
    sleep 10 # 设置每隔10s检测一次
    done
}
main

执行结果:

clipboard.png

5、开发一个shell脚本,实现cat命令的功能

这个脚本的知识点是while循环读取文件文件操作,while循环按行读取文件的方法有多种,下面是其中一种。

[root@moli_linux1 script]$ cat 10_6.sh 
#!/bin/bash
while read line
do
    echo $line
done<$1

效果如下:

[root@moli_linux1 script]$ sh 10_6.sh /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.30.2 ccc.com ddd.com

6、shell脚本解决DDoS攻击

分析web日志,可以每小时或者每分钟分析一次,例如将日志按小时进行分割,分成多个不同文件,然后分析这些文件,把单个文件中单个IP访问量超大的IP封掉。下例以nginx访问日志为例:

#!/bin/bash
path="/usr/local/nginx/logs/access.log" # Web日志文件
tmp_log_path="/tmp/nginx_tmp.log" # awk分析后的IP日志文件
while true
do
    # 把IP和IP对应的访问次数记录到新日志文件
    awk '{print $1}' ${path} | grep -v "^$"| sort | uniq -c >${tmp_log_path}
    exec < ${tmp_log_path}
    # 读取日志文件
    while read line
    do
        ip=`echo $line | awk '{print $2}'`
        count=`echo $line | awk '{print $1}'`
        # 如果IP的访问次数大于500而且iptables规则没有这个IP的规则,那么就封掉
        if [ $count -gt 500 ] && [ `iptables -n -L | grep ${ip}|wc -l` -lt 1 ];then
            iptables -I INPUT -s $ip -j DROP
            echo "iptables is open make $line is block." >> block_ip.log
        fi
    done
    sleep 3600 # 睡眠1小时
done

7、for循环的简单应用

7.1 批量修改文件名

某个目录下有如下几个文件,要求将每个文件的"_finished"去掉。
clipboard.png

脚本示例:

#!/bin/bash
path=/root/server/script/test
cd ${path}
for file in `ls *.jpg` # for遍历整个目录下所有以.jpg结尾的文件
do
    mv $file `echo $file|sed 's/_finished//g'`  # 这里使用sed命令将_finished字符串全部替换为空
done

执行结果:

[root@moli_linux1 script]# sh 11_4.sh
[root@moli_linux1 script]# ll test
总用量 0
-rw-r--r-- 1 root root 0 7月   7 12:54 stu_10299_1.jpg
-rw-r--r-- 1 root root 0 7月   7 12:55 stu_10299_2.jpg
-rw-r--r-- 1 root root 0 7月   7 12:55 stu_10299_3.jpg
-rw-r--r-- 1 root root 0 7月   7 12:55 stu_10299_4.jpg
-rw-r--r-- 1 root root 0 7月   7 12:55 stu_10299_5.jpg

7.2 打印九九乘法表

#!/bin/bash
COLOR='\E[47;30m'
RES='\E[0m'
for n1 in `seq 9`
do
    for n2 in `seq 9`
    do
        if [ $n1 -ge $n2 ];then
            if ((n1*n2>9));then
                echo -en "${COLOR}${n1}x${n2}=$((n1*n2))${RES} "
            else
                echo -en "${COLOR}${n1}x${n2}=$((n1*n2))${RES} "
            fi
        fi
    done
echo "  "
done

执行结果:

clipboard.png

7.3 用for循环实现mysql数据库分库备份脚本
编写shell脚本将mysql数据库里的三个库harutya1,2,3备份出来,并且按照日期将备份文件进行压缩。

clipboard.png

不登录mysql进行单库备份的命令是:

mysqldump -uroot -p123456 -S /tmp/mysql.sock hatutya1| gzip>/root/server/script/test/harutya1_$(date +%F).sql.gz

脚本实现:

#!/bin/bash
DBPATH="/root/server/backup" 
BACKUP_USER="root"
BACKUP_PASSWD="123456"
SOCKET="/tmp/mysql.sock"
MYCMD="mysql -u${BACKUP_USER} -p${BACKUP_PASSWD} -S ${SOCKET}"
MYDUMP="mysqldump -u${BACKUP_USER} -p${BACKUP_PASSWD} -S ${SOCKET}"
[ ! -d "${DBPATH}" ] && mkdir -p ${DBPATH}
for dbname in `$MYCMD -e "show databases;" 2>/dev/null|sed '1,2d'|grep "harutya"`
do
    $MYDUMP $dbname 2>/dev/null |gzip>$DBPATH/"$dbname"_$(date +%F).sql.gz
done

执行结果:

clipboard.png

8、Linux产生随机数的几种方法

8.1 通过系统变量$RANDOM

$RANDOM的随机数范围是0-32767,加密性不是很好,可以通过输出随机数后增加加密字符串的方式解决,最后结合md5sum操作并截取结果的后n位,这样就可以生成较复杂的随机数了,可用作用户密码等。

[root@moli_linux1 script]# echo $RANDOM # 输出简单的数字
21572
[root@moli_linux1 script]# echo $RANDOM
19201
[root@moli_linux1 script]# echo "harutya$RANDOM"|md5sum |cut -c 8-15 # 与md5sum结合再使用cutM命令进行截取
d2c2f1d9

8.2 通过opensll产生随机数

[root@moli_linux1 script]# openssl rand -base64 8
6tFdSQqMwrc=
[root@moli_linux1 script]# openssl rand -base64 80
88ASydNvD8KQxM8N2TnSTCZR7fXVZETPL1BGOAUMv7ZbTS6hxnIGJZdJ0FoCj2Gn
WSMQkSn3JdMrgz2o8oH78QaNh2kpBo0ht7CSN7If+EY=

8.3 通过date命令

[root@moli_linux1 script]# date +%s%N
1562481571763444791
[root@moli_linux1 script]# date +%s%N
1562481573090353690
[root@moli_linux1 script]# date +%s%N
1562481575834864133

8.4 mkpasswd命令

选项:

  • -l(是L不是1):指定密码的长度,后面数字9表示生成的密码有9位,默认7位;
  • -d:指定密码中数字最少是几位,默认2位;
  • -c:指定密码中小写字母最少是几位,默认2位;
  • -C:指定密码中大写字母最少是几位,默认2位;
  • -s:指定密码中特殊字符最少位数,默认是1位

示例,生成9位长的密码,数字最少有2位,小写字母和大写字母都至少有3个,特殊符号至少1个:

[root@moli_linux1 script]# mkpasswd -l 9 -d 2 -c 3 -C 3 -s 1 
r9kELr~F3
[root@moli_linux1 script]# mkpasswd -l 9 -d 2 -c 3 -C 3 -s 1
euvS2J\7L
[root@moli_linux1 script]# mkpasswd -l 9 -d 2 -c 3 -C 3 -s 1
~id0RG3Aq
阅读 1.3k

推荐阅读