52.运维9-shell

77.shell 1:

10,20s/^/#/g   10到20行加上#
d^  删除光标前面的
d$  删除光标后面的
dw  删除两个分隔符之间的文字
3yy  p
0.Shell简介
    1.为什么要学习Shell (工作职责 )
        1)安装操作系统(1.手动安装2.工具自动化安装(kickstart cobbler) 3. 网络安装)
        2)系统优化(面试)关闭SElinux
        Firewalld (防火墙工作中必须开启的对外的场景)内部的测试服务器无所谓,SsH优化
        加大文件描述符内核参 数优化yum源安装常用的软件ntp时间同步字符集调整....
        在工作中系统优化全部是以脚本的方式运行
        3 )安装服务Nginx apache (yum install httpd) PHP MySQL keepalived Zabbix SErsync NES
        Redis Mongo Memcache KVM Docker K8S
        ELK
            使用脚本安装工
        4)修改配置文件,启动服务( systemct start stop reload restart status )
            公司自主研发(使用py开发的程序)
        5)日志监控日志切割脚本+定时任务( rsync+sersyne) 脚本+定时任务ELK
        6)日志统计使用三剑客+命令做日志分析
        7)数据备份数据库备份存三份
        8) zabbix(常用) Nagios (交换路由大型公司宽带运营商使用)Cacti (重要 监控流量)
        脚本把数据统计出来使用zabbix进行监控
    2.学习Shell所需的知识
        1) xshell CRT
        2)Linux常用的基础命令
    
1. Shell入门
    1)什么是Shell
       [root@web01 /etc/zabbix/zabbix_agentd.d]# cat /etc/shells
        /bin/sh
        /bin/bash
        /usr/bin/sh
        /usr/bin/bash
        /bin/tcsh
        /bin/csh
        命令解释器,负责翻译我们输入的命令,执行成功返回给用户
        面试题: linux 默认的Shell是(bash )
        交互式:用户输入命令,bash负责把我们的命令翻译成内核可识别的语言,返回结果到屏幕
        非交互式:不与用户进行交互,执行文本里的内容,执行到文件的末尾,结束
    2)什么Shel1脚本
        命令的集合命令大礼包很多可执行命令放在文本中称为shell脚本(包含条件表达式
        判断语句数组等等)

    语言种类: C  C++ python JAVA perl go PHP
        会python还需要会shell么?  需要
2.shell脚本规范?(规范为了自动化)
	1.必须放在同一的目录
    2.脚本必须以.sh结束
    3.脚本开头有注释#!/bin/bash必须是第一行 以外都是注释
    4.脚本的注释信息代码块的注释
    5.建议注释使用中文
    6.成对的符号一次性写完
    7.脚本名称最好建明知意
    
3.shell特殊位置变量
	$0 代表了脚本的名称 如果全路径执行 则脚本名称待全路径
    grep '$0' /etc/init.d/network
    basename test.sh  # 获取脚本名称
    
    $n sh test.sh oldboy  # 就是脚本后面的第n个参数 ${9}之后需要将{},表示一个整体
    
    $# 获取脚本传参的总个数 对参数总个数做控制
      [ $# -ne2 ] $$ echo "请输入两个参数" $$ exit  # &&前面成功才执行后面的
    
    $* 获取脚本所有的参数 不加引号和$@相同 加上引号 真把参数视为一个参数$1$2$3
    $@ 获取脚本所有的参数 不加引号和$*相同 加上引号 真把参数视为独立参数 $1 $2 $3
       $@和$*在脚本中相同 再循环体中不同
    [root@web01 scripts]# for i in "$*";do echo $i;done
        I am lizhenya teacher
    [root@web01scripts]# for i in"$@";do echo $i;done
        I am
        lizhenya
        teacher
    $? 获取上一天命令的返回结果 0未成功 非0失败  ****
    $$ 获取脚本的PID
       kill `cat nginx.pid`
    $! 获取上一个脚本后台运行的pid
    $_ 获取命令左后一个参数   类似esc .
       
4. 字串的删除和替换
        # 从前向后匹配删除 ## 贪婪匹配
        [root@oldboy scripts]# echo Surl
        	www.sina.com.cn
        [root@oldboy scripts]# echo ${ur1#*.}  # 使用#匹配从*开始到.结束
        	sina. com. cn
        [root@oldboy scripts]# echo ${ur1#*.*.
        	com. cn
        [root@oldboy scripts] #echo ${ur1#*.*.*.}
        	cn
        [roottoldboy scripts]# echo $ {url ##*.}
        	cn
        # 从后向前匹配删除 ## 贪婪匹配
       [root@oldboy scripts]# echo $url
         www. sina. com. cn
        [rootdoldboy scripts] # echo ${ur1%.★}
          www. sina.com
        [root@oldboy scripts]井echo ${ur1%.*.*}
         www. s1na
        [root@oldboy scripts]# echo$ {ur1%%.*}
        WWwW
       # 替换
       [root@oldboy scripts]#echo $ur1
        www. sina.com.cn
        [root@oldboy scripts]# echo $ {ur1/w/a}
        aww. sina.com.c cn
        [ root@oldboy
        scripts] # echo${ur1/ /w/a}
        aaa. s1na.com.c cn
       
5.数值计算
   1:expr支持整数运行  # 判断数字是否是整数
       expr 1 + 1
       expr 1 \* 1
       expr 1 + $num >/dev/null 2>&1
       [ $? -ne 0 ] $$ echo "请输入整数" $$ exit 1
   2:$(())  整数运算
       $((10+10))
   3.$[] 整数运算
       echo $[10+10]
   4:bc 整数小数运算
       echo 10+10.5|bc
   5.awk 整数小数运算
       awk 'BEGIN{print 1+ 1.5}'
       echo 10 12|awk '{print $1*$2}'
  
6. shell三种参数方式
      # 第一种传参方式 赋值
       name=$1
       age=$2
       echo name age
      # 第二种方式 read
       read -p "please input name: " name
       echo $name
       
      # 第三种方式 $age
       echo $1 $2
       
7. 环境变量字串
    字串切片和长度统计
    [root@oldboy scripts]# echo $test
    	i am lizhenya teacher
    [root@oldboy scripts]# echo ${test:0:2}
         i
    [root@oldboy scripts]# echo ${test:0:3}
    	i a
    [root@oldboy scripts]# echo ${test:2:2}
    	am
    [root@oldboy scripts]# echo ${test:1:3}
    	am
    [root@oldboy scripts]# echo ${test:6:10)  # 6后面10个字符
    	izhenya te
    [root@oldboy scripts]# echo ${test:5:10}
        lizhenya t
       
    试题:
    统计以下字符串输出小于3的字符
    如何统计字符串长度
    [root@oldboy scripts]# echo ${#test}
       6
    [root@oldboy scripts]# echo $test|wc -L 
       6
    [root@oldboy scripts]# expr length $test
       6
    [root@oldboy scripts]# echo $test| awk '{print length}'
       6
       
    第一种答案
    [root@oldboy scripts]# cat for. sh
    #! /bin/sh
    for i in I am lizhenya teacher I am 18
    do
    	[ ${#i} -lt 3 ]&&echo $i
    done
    第二种答案awk列方式
    echo "I am lizhenya teacher I am 18|xargs n1|awk '{if (length<3) print}'
            
    第三种答案横向判断
    echo "I am lizhenya teacher I am 18"| awk'{for(i=1;i<=NF;i++)if(length($i)<3)print $i}'、
            
8.条件表达式
    文件测试
    test=[] / []
    常用
    -e file存在则为真
    -f file是否为文件
    -d file是否为目录是否存在
    -x file是否可执行
    -r file是否可读
    -w file是否可写
    -s file是否为socker文件
    [root@oldboy scripts]# [-e /etc/hosts ]  == test -e /etc/hosts
    [root@oldboy scripts]# echo $?
    0        
    [root@oldboy scripts]# [ -e /etc/hostssss ]
    [root@oldboy scripts]# echo $?
    0        
    [root@oldboy scripts]# [ -f /etc/hostssss ]
    [root@oldboy scripts]# echo $?
    1        
    [root@oldboy scripts]#[ -f /etc/hostssss ] && echo ok || echo error  返回0执行&&后命令,否则执行||后命令
    error
    [root@oldboy scripts]# [ -f /ete/hosts ] && echo ok || echo error
    ok
    [root@oldboy scripts]# [ -d /ete/hosts ] && echo ok || echo error   
    error
    # 加载函数库
    ./etc/init.d/functions
    [ -d /backup] $$ action "Nginx start is" /bin/true || actions "Nginx start is" /bin/false
            
   数值比较
    语法格式[数值1比较符数值2 ]
    比较符
    -eq 等于
    -ne 不等于
    -gt 大于
    -ge 大于等于
    -lt 小于
    -le 小于等于
    [[]] 建议使用== != > < >= <=比较符
    [rooteoldboy scripts]#↓10 -eq10 ] && echo $?|| echo $?==[10 -eq 101:echo $?
     案例1:磁盘使用率
     #!/bin/bash
    disk=`df -h|grep /$|awk '{print $(NF-1)}'`
    [ ${disk%\%} -gt 80 ] && echo "磁盘使用超过百分之八十,当前使用率$disk" || echo "操盘正常,当前使用率$disk"
     案例2:内存使用率
     [root@web01 ~]# [ `free|awk 'NR==2{print ($3/$2)*100}'|awk -F. {print $1}` -gt 5] $$ echo mail|| error
	27.693
     案例3:统计负载情况 一种负载大于3 报警发邮件
     [root@web01 ~]# ab -n 200000 -c 20000 http://127.0.0.1/index.html # -n总次数 -c并发次数     
     [root@web01 ~]# uptime|awk -F '[ ,.]+' '{print $12}'
     21
            
9.多整数比较
     [root@web01 ~]# [ 10 -ge 10 -a 10 -gt 5 ] && echo "成立" || echo "不成立"
    成立
    [root@web01 ~]# [ 10 -ge 10 -o 10 -gt 5 ] && echo "成立" || echo "不成立"
    成立
    [root@web01 ~]# [ 10 -ge 10 -o 10 -gt 5 -a 100 -ge 101 ] && echo "成立" || echo "不成立"
	成立     
    [root@web01 ~]# [[ 10 -ge 100 && 199 -lt 200 ]] && echo "成立" || echo "不成立"
	不成立  
    [root@web01 ~]# [[ 10 -ge 100 || 199 -lt 200 ]] && echo "成立" || echo "不成立"
	不成立        

78.shell2:

10.环境变量
    1)什么是环境变量
        x=1 y=x+1 xy===变量名称等号右边=- =变量值 =赋值
        右边一堆内容,使用一个名字来代替称为环境变量
    2)环境变量分类
        1.环境变量(全局变量)
        2.普通变量(局部变量)
        按照生命周期划分两类
        永久的需要在环境变量文件中配置/etc/porfile永久生效
        临时的使用export声明即可临时生效重启失效
        test=lizhenya中只对当前的bash生效
        export test= lizhenya对(当前)所有的bash生效
        写入/etc/profile针对所有用户和bash生效
        补充:
        如何查看变量
        env
        Set
        变量生效顺序 # 按顺序
            /etc/profile开机所有用户加载此文件
            . ~/.bashrc   
            . bash_ profile
            .bashrc
            /etc/bashrc
    3)设置在如下文件中
    		/etc/profile开机所有用户加载此文件
            . ~/.bashrc   
            . bash_ profile
            .bashrc
            /etc/bashrc
11.字符创比较
     [root@web01 ~]# [ "$USER" == 'root' ] && echo 1 ||echo 0
	1
    -n STRING the length of STRING is nonzero  字符串长度不为0,返回真
    -z STRING the length of STRING is zero 字符串长度为0,返回真
    [root@web01 ~]# [ -z "fdsf" ]
    [root@web01 ~]# echo $?
    1
    [root@web01 ~]# [ -n "fdsf" ]
    [root@web01 ~]# echo $?
    0
    -z案例:判断是否为空,必须得输入字符,不输入则退出
        #! /bin/sh
        read -P 请输入要更改的主机名:”name
        [ -z $name ] && echo "请输入主机名称" && exit
    案例:判断是否为整数
        expr 1 + 变量
        xBF -ne01e echo "请输入整数"“exit
        
12.正则比对

    需要使用[[] ]
    [rootroldboy scripts]# [[ $USER =~ ^r ]]  # ~后面必须有空格
    [roottoldboy scripts]# echo $?
    [rooteoldboy scripts]# [[ $USER =~ ^1 ]]
    [roottoldboy scripts]# echo $?
    1
    [roottoldboy scripts] # [[ ! $USER=~ ^1]]  # !后面必须有空格
    [root@oldboy scripts]# echo $?
    0
    [roottoldboy scripts]#test=123
    [root@oldboy scripts]# [[ $test =~^[0-9]+$ ]]
    [root@oldboy scripts] #
    [root@oldboy scripts]# echo $?NH
    [root@oldboy scripts]# test=123qqq 
    [rooteoldboy scripts] # [[ $test =~ ^[0-9]+$ ]]  # 判断是否为整数
    [rooteoldboy scripts]# echo
    案例1:
        使用三种传参方式 比较两个数值的大小打了提示大了 小提示小了
        [root@web01 /server/scripts]# cat bijiao.sh 
        #!/bin/bash
        read -p "请输入一个整数" num1 num2
        [ -z $num1 -o -z $num2 ] && echo "不能输入空" && exit  
        [[ ! $num1 =~ [0-9]+$ && ! $num2 =~ [0-9]+$ ]] && echo "请输入整数" && exit
        [ $num1 -gt $num2 ] && echo "$num1大于$num2" || echo "$num1小于等于$num2"
        
   案例2:使用脚本统计出  系统的名称 服本号 内核版本 虚拟平台 lo IP地址 eth0 IP地址 外网ip地址 当前磁盘使用率当 前内存使用率
    当前负载
    shtestah
    oldboy
    ethOIP地址为: 10.0.0.7
    外网Ip地址:cur1 cip.cc
        
  案例3:linux添加默认路由 添加多个IP地址
    route add default gw 192.168.31.44  # 添加默认路由
    route del default gw 192.168.31.44
    ip route add 0/0 via 192.168.31.44  # 添加默认路由
    ip route del 0/0 via 192.168.31.44
    
    ip add add 192168.31.33/24 dev eth0  # 添加ip地址
    ip add del 192168.31.33/24 dev eth0  # 删除ip地址
    
    ip ro list  # 查看策略路由
    cat /etc/iproute2/rt_tables  # 策略路由表
    [root@web01 /server/scripts]# cat /etc/iproute2/rt_tables|grep -v "^#"
    255	local
    254	main
    253	default
    0	unspec
    200 test  # 比前面的小,优先级就高
    # 添加一个表 给这个表设置一个路由
    ip route add 0/0 via 10.0.0.254 table test  # 只要是table中的都走的是10.0.0.254这个网关
    ip rule add from 10.0.0.1 table test  # 只要从10.0.0.1进来的路由,使用test表中定义的网关出去
    
13.循环
	for i in [取值列表]  数字 字符串 命令的结果`` 序列
    do
    	要执行的命令
    done
    ping -c2 -W1 10.0.0.2  -c次数 -W等一秒
    1.批量pingip
    for i in {1..200}
    do
    	{
    	ping -c1 -W1 192.168.31.$i  >/dev/null 2>&1
        [ $? -eq 0 ] && echo $IP
        } &
    done
    wait
    echo "ping完成"
    2.批量创建用户
    read -p 'please input prefix' pre num
    [ -z $pre ] && echo "请输入pre" && exit
    [[ ! $num =~ [0-9]+$ ]] && echo "请输入整数" && exit
    for i in `seq num`
    do
    	user add $per$i
        [ $? -eq 0 ] && echo "创建成功" || ehco "创建失败"
        echo 123456|passwd --stdin >/dev/null 2>&!
    done
    
14.if判断
	if [ niyouqina ]
    then
    	echo 1
    if
    #
    if [ 你是啥不 ]
    then 
    	echo 2
    elif [ 你有房 ]
        echo 3
    fi
    #
    if [ niyouqina ];then
    	echo 1
    elif [ nishis ];then
    	echo 2
    elif [ afdsf ];then
      	echo 3
    elif [ fadsffas ]; then
    	echo 4
    else
    	echo XXXX
    if
    总结:
        单分支 一个条件 一个结果
        多分支 多个条件 多个结果
        
   案例1:判断输入的两个数字的大小输出结果
    [ $num -eq $num2 ] && echo $num =$num2
    read -P请输入两个整数” num1 num2
    if [ $num1 -gt $num2 ];then
        echo $nurml > $num2 
    elif [ $num1 -lt $nlum2 ];then
        echo S num1< S num2
    else
        echo $num1 = $ num2
    fi     
   
    [root@web01 /server/scripts]# echo $((RANDOM%100+1))  # 生成随机数100表示100以内,最多只有五位
    81
    
    案例2:先输出一一个随机数,read猜随机数
    如果你输入的小了则提示小了脚大了就提示大了如果成功则提示猜对了
    echo "$RANDOM*100+1 ”
    [root@oldboy scripts]# cat ran. sh
    #!/bin/sh
    ran= echo $ ( (RANDOMA100+1) )
    while true
    do
    	let i++
    read -P "请输入你要猜的数字:”num
    if[ $num -gt $ran];then
    	echo "比随机数大了”
    elif [ $num -lt $ran ] ; then
    	echo比随机数小了”
    else
        echo"恭喜你猜对了总共猜了$i次"
        exit
    fi
    done
    
    案例3:按照不同的centos版本安装不同的yum源
    1.当前什么版本如何取出来
    2. if判断如果是6则安装6的yum源7安装7yum源5的安装5的yum源
    [root@oldboy scripts]# cat osversion. sh
    #!/bin/sh
    os=`cat /etc/redhat-releasel awk '{print $ (NF-1)}'`
    	[ "$os"== "xxx"] && os=取centos6版本的命令
    if[ ${os%%.*} -eq 7] ;then
        which wget >/dev/nu11 2> &1
        [ $? -ne 0] && yum-Y install wget
        #mv letc/yum. repos. d/Centos-Base. repo /etc/yum. repos. d/Centos-Base. repo.backup
        #wget -。/etc/yum. repos.d/Centos-Base. repo http; , /mirrors. aliyun, com/repo/centos-7.repe
        echo "yum install is done.
    elif [ ${os%%.*} -eq 6] ;then
        which wget > /dev/nu11 2>&1
        [ $? -ne 0 ]&& yum -y install wget
        wget -0 /etc/yum. repos.d/Centos-Base.repo http://mirrors. aliyun.com/repe/centes-6.r.p2
    else
        which wget > /dev/nu11 2>&1
        [ $? -ne 0 ] && yum -y install wget
        wget -。/etc/yum. repos.d/Centos-Base.repo http://mirrors.aliyun.com/repe/centos-5.repe
    fi
    
    案例4:菜单
     菜单的使用方法:
    [root@oldboy scripts]# sh menu.sh
    ##############1.PHP install5.5 #######
    ##############2.PHP install5.7 #######
    ##############3.PHP instal17.1 #######
    ##############4.PHP install7.2 #######
    cat<< E OF
            1.INSTALL PHP5.5
            2.INSTALL PHP5.6
            3.INSTALL PHP7.1
            4.INSTALL PHP7.2
    EOF

79.shell3:

15.case
	结构
    变量 == 名字 自己起的 脚本名称 $1 $2
    case $1 in             if [ $1 == oldboy ];then echo
    	模式1)
        	命令大礼包
            ;;
        模式2)
        	命令大礼包
            ;;
        模式3)
        	命令大礼包
            ;;
            *)
            echo 没有匹配
    esac

	案例1:批量删除用户(if也可以)
        1.删除用户的前缀read -p "prefix" pre
        2.删除用户的数量 read -p "num" num
        [root@web01 /server/scripts]# cat userdel_.sh 
        #!/bin/bash
        read -p "prefix" pre num
        for i in `seq $num`
        do
            echo $per$i
        done
        read -p "确定删除以上用户?y/n" te
        for i in `seq $num`
        do
            user=$pre$i
        case $te in 
            y|Y|yes)
                  id $user >/dev/null 2>&1
                  if [ $? -eq 0 ];then
                        userdel -r $user &>/dev/null
                  else
                    echo "id:$user:no such user"
                  fi
                  ;;
                n|N|nO)
                    exit
        esac
        done
        
     案例2:case 使用菜单显示
        1.help帮助 答应菜单
        2.显示内存使用
        3.显示磁盘使用
        4.显示系统负载
        5.显示登录用户
        6.查看ip地址
        7.查看Linux-version
        [root@web01 /server/scripts]# cat xitong.sh 
        cat << EOF
                1.help帮助 答应菜单
                2.显示内存使用
                3.显示磁盘使用
                4.显示系统负载
                5.显示登录用户
                6.查看ip地址
                7.查看Linux-version
        EOF
        read -p "请输入要查看的选项:" num
        case $num in
             1)
                echo "欢迎使用"
                ;;
             2)
                echo "内存使用了`free|awk 'NR==2{print  $3/$2*100}'|awk -F. '{print $1"%"}'`"
                ;;
             3)
                echo "`df -h|grep '/$'|awk '{print $(NF-1)}'`"
                ;;
             5)
                echo "$USER"
                ;;
             6)
                echo "`hostname -I|awk '{print $1}'`"
                ;;
             7)
                echo "系统版本`cat /etc/redhat-release|awk -F '[ .]+' '{print $4}'`"
                ;;
             4)
                echo "`uptime|awk -F '[ ,]' '{print "1m负载:"$(NF-4), "5m负载:"$(NF-2),"15m负载:"$NF}'`"
                ;;
             *)
                echo "滚"
        esac
        
       案例3: Nginx 启动脚本
            命令行方式启动Nginx
            /usr/sbin/nginx 启动命令
            /usr/sbin/nginx stop停止命令
            /usr/sbin/nginx -s reload重新加载 
            # 重启
            /usr/sbin/nginx -S stopa
            sleep 2
            /usr/sbin/nginx
            查看状态
            手动过滤出监听的端口和Nginx的PID打印输出
       [root@web01 /server/scripts]# cat start_ngin.sh 
        #!/bin/sh
        name=$1
        [ -f /etc/init.d/functions ] && . /etc/init.d/functions
        start(){
            /opt/nginx1-12/sbin/nginx &>/dev/null
        }
        stop(){
            /opt/nginx1-12/sbin/nginx -s stop &>/dev/null
        }
        restart(){
            stop
            sleep 2
            start
        }
        status(){
            echo "`netstat -tunlp|grep nginx|awk '{print $4}'`"
        }
        reload(){
            /opt/nginx1-12/sbin/nginx -s reload &>/dev/null
        }
        test(){
            if [ $? -eq 0 ];then
            action "Nginx $name is" /bin/true
            else
            action "Nginx $name is" /bin/false
            fi
        }
        case $1 in 
            start)
                start
                test;;
            stop)
                stop
                test;;
            restart)
                restart
                test;;
            reload)
                reload
                test;;
            status)
                status;;
            *)
                echo "USEAG $0 [start|stop|reload|restart|status]"
        esac
        
     案例4:跳板机   
    [root@web01 /server/scripts]# cat jumpersuper.sh 
    #!/bin/sh
    WEB1=172.16.1.7
    WEB2=172.16.1.8
    WEB3=172.16.1.9
    MYAQL=172.16.1.51
    NFS=172.16.1.31
    menu(){
    cat << EOF
        1. WEB1=172.16.1.7
        2. WEB2=172.16.1.8
        3. WEB3=172.16.1.9
        4. MYAQL=172.16.1.51
        5. NFS=172.16.1.31
        6. menu
    EOF
    }
    menu
    trap "请不要乱按,小心机器炸了" INT TSTP HUP  # 限制ctrl+c或者ctrl+d之类的退命令
    while true
    do
    read -p "请输入需要连接的主机名编号:" num
    case $num in
        1)
        ssh root@$WEB1
        ;;
        2)
        ssh root@$WEB2
        ;;
        3)
        ssh root@$WEB3
        ;;
        4)
        ssh root@$MYSQL
        ;;
        5)
        ssh root@$NFS
        ;;
        6)
        menu
        ;;
        woshiyunwei)
        exit
        ;;
        *)
        read -p "请输入需要连接的主机名编号:" num
    esac
    done	
    
16.while 回顾for
	
	for i in `cat user.txt`;do useradd $i;done
    while [ 条件表达式 ]
    do
    	命令
    done
    案例1:创建用户名密码
    while read line   # 读一行
    do
    	user=`echo $line|wak '{print $1}'`
        pass=`echo $linx|awk '{print $2}'`
    	useradd $user
        echo $pass|passwd --stdin $user
    done < user.txt
    
17.shell的内置命令
	exit(直接退出) continue(跳出本次循环,执行下次循环) break(直接退出)
    while true
    do
    	echo 123
        exit/continue/break
    done
    
    案例1:猜随机数
    [root@web01 /server/scripts]# cat ran.sh 
    #!/bin/sh
    ran=`echo $((RANDOM%100+1))`
    while true
    do
        let i++
    read -p "请输入要猜的数字:" num
    if [ $num -gt $ran ];then
        echo "比随机数大了"
    elif [ $num -lt $ran ];then
        echo "比随机数小了"
    else
        echo "恭喜猜对了 总共才了$i次"
        exit
    fi
    done
    
18.函数
	书写方式:
	[root@web01 /server/scripts]# cat fun.sh 
    #!/bin/sh
    test(){
        echo "1"
    }
    function test2(){
        echo "2"
    }

    function test3 {
        echo "3"
    }
    test
    test2
    test3
    
    传参方式:
    [root@web01 /server/scripts]# cat fun.sh 
    #!/bin/sh
    test(){
        echo "$1"
    }
    function test2(){
        echo "$1"
    }

    function test3 {
        echo "$1"
    }
    test $1
    test2 $2
    test3 $3
    [root@web01 /server/scripts]# sh fun.sh 12 23 34
    12
    23
    34
    
    案例1:
    [root@web01 /server/scripts]# cat fun_c.sh
    #!/bin/sh
    count01(){
    num=10
    for i in `seq 10`
    do
        total=$[$i + $num]
        echo "$total"
    done
    }
    count01  
    
    案例2:
    [root@web01 /server/scripts]# cat fun_c.sh
    #!/bin/sh
    count01(){
    for i in `seq 10`
    do
        total=$[$i + $num]
        echo "$total"
    done
    }
    num=10
    count01 
    [root@web01 /server/scripts]# sh fun_c.sh 10
    结果:20
    
    案例3:
    [root@web01 /server/scripts]# cat fun_c.sh
    #!/bin/sh
    count01(){
    for i in `seq 10`
    do
        total=$[$i + $1]
        echo "$total"
    done
    }
    count01 $1
    count01 $2
    count01 $3
    [root@web01 /server/scripts]# sh fun_c.sh 10 20 30
    结果:20 40 60 
        
    案例4:
    [root@web01 /server/scripts]# sh fun_c.sh 
    函数的状态码是: 1
    函数的执行结果是: 100
    [root@web01 /server/scripts]# cat fun_c.sh 
    #!/bin/sh
    fun3(){
        echo 100
        return 1
    }
    result=`fun3`
    echo "函数的状态码是: $?"
    echo "函数的执行结果是: $result"  
    
    案例5:
    [root@web01 /server/scripts]# sh fun2.sh /etc/host
    [root@web01 /server/scripts]# echo $?
    1
    [root@web01 /server/scripts]# cat fun2.sh 
    file=$1
    t_file(){
    if [ -f $file ];then
    return 0
    else
    return 1
    fi
    }
    t_file
	[ $? -eq 0 ] && echo "$file is ok" || echo  "$file is error"
    
    案例6:统计文件行
    [root@web01 /server/scripts]# sh fun3.sh /etc/hosts
    16
    [root@web01 /server/scripts]# cat fun3.sh 
    #!/bin/bash
    file=$1
    count(){
        local i=0
    while read line
    do
        let i++
    done <$file
    echo $i
    }
    count
    # 统计文件行数
    awk '{print NR,$0}' /etc/hosts
    [root@web01 /server/scripts]# wc -l /etc/hosts
    [root@web01 /server/scripts]# cat -n /etc/hosts
    [root@web01 /server/scripts]# grep -n . /etc/hosts
    [root@web01 /server/scripts]# less -N /etc/hosts
    [root@web01 /server/scripts]# sed '=' /etc/hosts
    
    案例7:中午吃啥?随机生成中午要吃哪一家?
        1.黄焖鸡
        2.包子
        3.炒菜
        4.豆浆
        5.拉面
        6.水饺
        7.盖饭
        8.撸串
        9.沙县
        10.不吃了
        
   [root@web01 /server/scripts]# cat etc.sh
    #!/bin/bash
    num=$((RANDOM%10+1))
    case $num in
        1)
            echo "黄焖鸡"
        ;;
        2)
            echo "包子"
        ;;
        *)
            echo "随便"
    esac
    
    案例8:引入脚本和变量
    [rooteoldboy scripts]# cat fun2. sh
    count01 () {
    for i in `seq 10`
    do
    	total=$[$i+ $ num]
    done
    	echo计算结果是: $total"
    }
    num=10
    count01
    我在另外脚本调用你的结果计算结果是:20
    10
    [root@ol dboy scripts]# cat funtest.sh
    #! /bin/sh
    . /server/ scripts/fun2.sh > dev/null 2>&1
    echo "我在另外脚本调用你的结果清`count01`"
    echo $num

80.shell数组:

1.
    [root@oldboy ~]# echo $ {array}
    linux
    [ root@oldboy ~]# array[1]=MySQL
    [root@oldboy ~] # array[2]=NES 
    [root@oldboy ~]# array[3]=She11
    [root@oldboy ~]# echo ${array}
    1 inux
    [rooteoldboy ~]# echo $ {array[3]}
    Shell
    [root@oldboy ~]# echo ${array[1]}
    MySQL
    [root@oldboy ~]# echo $ {array[2]}
    NFS
    [coot@oldboy ~]# echo ${array[*]}
    linux MySQL NeS Shell
    [root@oldboy ~]# echo ${array[@]}    # 获取所有制
    inux MySQL NeS shel1
    [coot@oldboy ~]# echo ${!array[@]}   # 获取索引
    0 1 2 3
    [root@oldboy ~]# echo ${!array[*]}
    0 1 2 3
    unset array  # 取消数组
    [root@web01 /server/scripts]# array=([0]=linux [1]=mysql [2]=shell [5]=nosql)
    [root@web01 /server/scripts]# declare -a  # 查看所有的变量
    
2.
	[root@web01 /server/scripts]# array=(linux shell mysql)
    [root@web01 /server/scripts]# echo ${!array[@]}
    0 1 2
    
    案例1:
        [root@web01 /server/scripts]# sh arrays.sh 
        1
        2
        3
        [root@web01 /server/scripts]# cat arrays.sh
        #!bin/bash
        ip=(
        1
        2
        3
        )
        for i in ${ip[*]}
        do
            echo $i
        done
        
3.关联数组
	关联数组
    字符串作为索引
    declare -A 数组名 	声明是一个关联数组 (awk中不需要定义关联数组)
    declare -A 查看关联数组
    declare -A array
    array= ([index] =Linux [ index1]=She1l [ index2]=KVM [ suiyiqi]=MySQL)
    
    案例1:命令行统计一行数据出现的次数
    [root@oldboy scripts]# let array[f]++
    [root@oldboy scripts]# let array[f]++
    [root@oldboy scripts] #
    [root@oldboy scripts]# echo ${array[m]}
    [rooteoldboy scripts]# echo ${array[f]}
    2
    [root@oldboy ~]# let array[f]++
    [root@oldboy ~]# let array[f]++
    [root@oldboy ~]# let array[m]++
    [root@oldboy ~]# let array[m]++
    [root@oldboy ~]# echo ${!array[*]}
    f m
    [root@oldboy ~]# for i inτ${!array[*]} ;do echo $i ;done
    f
    m
    [root@oldboy ~]# for i in ${!array[*]} ;do echo $ {array[$i]} ;done
    2
    3
    [root@oldboy ~]# for i in ${!array[*]} ;do echo $i,${array[$i]};done
    f,2
    m, 3
    [rooteoldboy ~]# for i in ${!array[*]} ;do echo $i $ {array[$1]》;done
    f 2
    m 3
    
    案例2:统计文件中某行数据出现的次数
    [root@web01 /server/scripts]# sh while.sh 
    f 3
    g 1
    m 4
    [root@web01 /server/scripts]# cat while.sh 
    #!/bin/bash
    declare -A array
    while read line
    do
        let array[$line]++
    done<sex.txt
    for i in ${!array[@]}
    do 
        echo "$i ${array[$i]}"
    done
    
    4.wak数组
    
    # 统计重复行
    [root@web01 /server/scripts]# awk -F: '{array[$NF]++}END{for (i in array) print i,array[i]}' /etc/passwd
    /bin/sync 1
    /bin/bash 3
    /sbin/nologin 43
    /sbin/halt 1
    /sbin/shutdown 1
    
    # 统计服务
    [root@web01 /server/scripts]# ss -an|awk '/:80/{tcp[$2]++}END{for(i in tcp) print i,tcp[i]}'
	LISTEN 1
    
    # 修改分隔符
    awk 'BEGIN{FS=":"}{print $1}' 
    # OFS指定输出分隔符
    awk 'BEGIN{FS=":";OFS="---"}{print $1,$2}' /etc/passwd  
    
    awk 'BEGIN{print 1/2}{print ok}END{print "game over"}'
    
    awk  -F ":" '/66/{print $1}' /passwd
    awk 'BEGIN{FS=":"} /66/{print $1}' /passwd
    
    awk '/\/$/{if ($3>5000) print $4}'
    
    # Awk工作原理
    # awk F: '{print $1,$3}'/etc/passwd
    1. awk将文件中的每一行作为输入,并将每一行赋给内部变量$0", 以换行符结束
    2. awk开始进行字段分解,每个字段存储在已编号的变量中,从$l开始[默认空格分割]
    3. awk默认字段分隔符是由内部FS变量来确定,可以使用-F修改
    4. ark行处理时使用了print函數打印分割后的字段
    5. awk在打印后的字段加上空格,因为$1,$3 之间有一个逗号.逗号被映射至OFS内部变量中,称为输字段分隔符,售OFS默认为空格.
    6. awk输出之后,将从文件中获取另一行,并将其存储在$o中,覆盖原来的内容,然后将新的字符串分隔成字段并进行处理。该过程将持续到所有行处理完毕,
    
    [root@web01 /server/scripts]# awk '{print NR, $0}' /etc/passwd /etc/hosts
    [root@web01 /server/scripts]# awk '{print FNR, $0}' /etc/passwd /etc/hosts
    
    awk -F":" '{print NF,$NF}' /passwd
    # 输出分隔符
    [root@web01 /server/scripts]# awk 'BEGIN{FS=":";OFS="+++"}/root/{print $1,$3}' /etc/passwd
    root+++0
    operator+++11
    # 换行符替换
    [root@web01 /server/scripts]# awk -F ":" 'BEGIN{RS=" "}{print $0}' /etc/passwd
    
    [rooteSbell ~]# date| awk '{print $2, "5月份-"\n",$NF,"今年"}'
    [rooteshell ~]#axk -F: '{print "用户是:"$1"\t "用户uid:"$3 "\t用户gid:"$4)' /etc/passed
    printf 函数
    [rooteSbell ~]# awk -F: '{printf "%6-15s %-10s %-15s\n", $1, $2, $3}' /etc/passwd
    %s字符类型
    %d数值类型
    占15字符类型
    表示左对齐,默认是右对齐
    printf默认不会在行尾自动换行,加\n

1.cpu:

https://blog.51cto.com/12758568/2122677  三剑客博客

81:练习

 x 1.写出以下Shell特殊位置参数变量的含义(5分)
    $0  获取脚本的名字,包含路径
    $n  $n(n=任意数字)代表脚 本在命令行的第几个参数
    $#  获取脚本参数的个数$*  获取当前shell脚本所有传参的参数,如果不加引号作用同$@相同,如果 加上双引号"$*则表示将所有的参数视为单个字符串相当于"$1$2$3" I
    $@  获取当前shell脚本所有传参的参数,不加引号同$*相同,加上双引号则 表示把所有的参数视为不同的独立的字符串
    $?  获取执行上一个指令执行状态返回值0为成功非零失败
    $$  获取当前shell脚本的进程号PID
    $!  获取上一个在后台工作脚本进程的进程号PID
2.如何定义环境变量    
	临时: export declare -x    
    永久: /etc/profile /etc/bashrc        
3.定义变量内容,不加引号、单引号、双引号、反引号结果有什么不同?应该怎么用? (5分)    
	不加引号:一般纯数字,简单连续的字符串也可以。    
    单引号:所见即所得,看见什么就输出什么。    
    双引号:默认是双引号,连续的字符串数字混合在一起,解析变量。    
    反引号:解析命令
                
4.写出下面特殊变量扩展的意义(5分)    
	${oldboy}   输出变量的内容,对变量 有保护作用
    ${#oldboy}  输出变量的长度。
    ${url#*.}   从前往后删除匹配最短的任意开头的字符到.的内容    
    ${url##*.}  从前往后删除匹配最长的任意开头的字符到.的内容    
    ${ur1%.*}   从后往前删除匹配最短的结尾是.开头的内容        
    ${url%%.*}  从后往前删除匹配最长的结尾是.开头的内容      
 5.数字的整数和小数有哪几种运算方式?      
      小数:awk bc      
      整数:expr $(()) $[]  let 1 + 1
 6.写出下面条件测试的含义(5分)   
      [ -e dir|file ] 存在则为真    
      [-d dir]    目录是否存在    
      [-f file]   文件是否存在    
      [-r file ]  文件是否有读权限    
      [-X file]   文件是否有执行权限    
      [-W file]   文件是否有写权限
 7.写一条判断语句,如果/tmp/oldboy.txt文件不存在则进行创建(5分)      
      [ -f /tmp/oldboy.txt] $$ echo "文件存在" || touch /tmp/oldboy.txt      
 8.查看当前磁盘/使用状态,如果使用率超过80%则把结果输出到/var/log/disk.err?      
      disk_info=`df -h |grep '/$'|awk {print $5}|wak -F % {print $1}`      
      if [ $disk_info -ge 80 ]      
      then        
      echo "磁盘是用了$disk_info%" >> /var/log/disk.err      
      fi      
9.批量创建10个用户,密码统一为123,需要对用户输入是否为数字和输入的名称是否为空进行判断?  
     	-n STRING the length of STRING is nonzero  字符串长度不为0,返回真
    	-z STRING the length of STRING is zero 字符串长度为0,返回真
    	[rootroldboy scripts]# [[ $USER =~ ^r ]]
      #!/bin/bash
      read -p "请输入用户名前缀和个数:" prefix num
      [ -n $prefix and -n $num ]
      [ $? ne 0] && echo "请输入前缀和个数" ;exit 1
      if [[ !$num =~^[0-9]+$]]
      then
      	echo "确保个数为数字";exit 2
      fi
      for i in `seq $num`
      do
      	username="$prefix$i"
      	useradd -M -s $username
      	passwd 123 $username
      	if [ $? eq 0 ]
      	then
      		echo "$username create ok"
      	fi
      done
      
10.猜数字随机一个100的数字要求用户数字(判断是否位数字),如果比随机数小则提示比随机数小了,大了则提示比随机数大了,最后统计猜了多少次?
      #!/bin/bash
        num=`echo $((RANDOM%100+1))`
        echo $num
        i=0
        while true
        do
        let i++
        read -p "请输入数字:" num2
        if [[ ! $num2 =~ ^[0-9]+$ ]]
        then
            echo "请输入数字";exit
        fi
        if [ $num2 -gt $num ]
        then
            echo "比随机数大了"
        elif [ $num2 -lt $num ]
        then
            echo "比随机数小了"
        else
            echo "恭喜猜对了 $num2"
            echo "猜了$i次"
            exit
        fi

        done
      
11.编写菜单
      [root@web01 /server/scripts]# cat caidan.sh 
        #!/bin/bash
        caidan(){
        cat << EOF
            h 显示帮助命令
            f 显示登录信息
            d 显示磁盘挂载
            m 查看内存使用
            u 查看系统负载
            q 退出程序
        EOF
        }
        caidan
        while true
        do

        read -p "请输入选项:" select
        case $select in 
            h)
                clear
                caidan
            ;;
            f)
                clear
                w
            ;;
            d)
                clear
                df -h
            ;;
            m)
                clear
                free
            ;;
            u)
                clear
                uptime
            ;;
            *)
                clear		
                exit 1
            esac
        done
      
12:用case语句写出nginx启动脚本
      	[root@web01 /server/scripts]# cat start_ngin.sh
        #!/bin/sh
        name=$1
        [ -f /etc/init.d/functions ] && . /etc/init.d/functions
        start(){
            /opt/nginx1-12/sbin/nginx &>/dev/null
        }
        stop(){
            /opt/nginx1-12/sbin/nginx -s stop &>/dev/null
        }
        restart(){
            stop
            sleep 2
            start
        }
        status(){
            echo "`netstat -tunlp|grep nginx|awk '{print $4}'`"
        }
        reload(){
            /opt/nginx1-12/sbin/nginx -s reload &>/dev/null
        }
        test(){
            if [ $? -eq 0 ];then
            action "Nginx $name is" /bin/true
            else
            action "Nginx $name is" /bin/false
            fi
        }
        case $1 in 
            start)
                start
                test;;
            stop)
                stop
                test;;
            restart)
                restart
                test;;
            reload)
                reload
                test;;
            status)
                status;;
            *)
                echo "USEAG $0 [start|stop|reload|restart|status]"
        esac
      
13.写一个脚本探测1-254之前存活的主机,输出到ip.txt.
      for i in {1..254}
      do
      	ip="192.168.31.$i"
      	ping $ip -c 1
      	if [ $? eq 0 ]
      	then
      	echo "$ip is exit" >> ip.txt
      	fi
      done
      
14.shell内置命令的含义
      exit 退出整个程序
      break 跳出循环
      continue 跳出本次循环执行下一次循环
      
15.普通数组和关联数组的定义方式
      普通数组:只能使用整数 作为数索引
      关联数组:可以使用字符串作用数组索引
      array=(linux shell mysql)
      declare -A array
      array= ([index] =Linux [ index1]=She1l [ index2]=KVM [ suiyiqi]=MySQL)
      
16.如何查看数组array元素的和索引的总个数?
      	echo ${!arrsy[*]}  索引
      	echo ${#array[*]}  元素
        [root@web01 /server/scripts]# array=(1 2 3)
        [root@web01 /server/scripts]# echo ${#array[*]}
        3
        [root@web01 /server/scripts]# echo ${!array[*]}|wc -w
        0 1 2
           
17.统计/var/log/nginx.log里ip访问次数
    [root@web01 /server/scripts]# awk 'NR<=10{print $1}' /opt/nginx1-12/logs/access.log|sort -n|uniq -c
      6 127.0.0.1
      4 192.168.31.68
18.统计下面的话中字母不大于6的单词?
    [root@web01 /server/scripts]# tail -1 backup.sh 
    rsync -az $backup_dir/ rsync_backup@172.16.1.41::backup --password-file=/etc/rsync.password
    [root@web01 /server/scripts]# tail -1 backup.sh |awk '{for(i=1;i<=NF;i++) if(length($i)>6) k++ ;print k}'3
    [root@web01 /server/scripts]# 
    方式一:
    [root@web01 /server/scripts]# tail -1 backup.sh |awk '{for(i=1;i<=NF;i++) {if(length($i)>6) print $i}  }'

$backup_dir/
rsync_backup@172.16.1.41::backup
--password-file=/etc/rsync.password
    方式二;
    array=(rsync -az $backup_dir/ rsync_backup@172.16.1.41::backup --password-file=/etc/rsync.password)
    for n in ${array[*]}
    do
    	if [ ${#n} -lt 7 ]
            then
            echo $n
            else
            continue
        fi
  	done
            
19. 计算从1加到100之和.
       [root@web01 /server/scripts]# seq 100|awk '{count+=$1}END{print count}'
5050
20.创建以随机十位字母+oldboy的.html文件,同时将oldboy替换为oldgirl
[root@web01 /server/scripts/oldboy]# ls
adfaffddga_oldgirl.html  boy.sh                   ehcceccbie_oldgirl.html  ffeecbhaef_oldgirl.html
bcjfiafida_oldgirl.html  cjbdeafcaj_oldgirl.html  fbgbeafihe_oldgirl.html  gdffaccfgi_oldgirl.html
bhcjfdbbae_oldgirl.html  dfbfibdajc_oldgirl.html  fdfiejbfad_oldgirl.html
[root@web01 /server/scripts/oldboy]# cat boy.sh 
#!/bin/bash
i=1
while [ $i -le 10 ]
do
	A=`echo $RANDOM|md5sum|tr '[0-9]' '[a-z]'|cut -c1-10`
	touch `echo ${A}_oldboy.html`
	let i++
done
for i in `ls *.html`
do
	mv $i `echo ${i/_oldboy/_oldgirl}` &>/dev/null
done
            
20.抓阄,根据输入随机选择三位同学出来.
[root@web01 /server/scripts/oldboy]# cat zhua.sh 
#!/bin/bash
>/tmp/pass
suess(){
	echo "下面三位同学去"
	cat /tmp/pass|sort -rk2|head -n 3
	exit 0
}
while true
do
    num=`mkpasswd -s 0 -d 2|sed 's/[a-zA-Z]//g'`	
	while [ `grep $num /tmp/pass|wc -l` -ne 1 ]
	do
		read -p "输入你的名字全拼:" name
		if [[ ! $name =~ [a-Z] ]]
		then
			echo "别瞎说了"
			break
		fi
		if [ $name = 'exit' ]
		then
			suess
		fi
		if [ `grep $name /tmp/pass|wc -l` -eq 1 ]
		then
			echo "重名了,请在后面加上数字"
			break
		fi
		echo "你的数字是:$num"
		echo -e "$name\t$num" >> /tmp/pass 
	done
done
posted @ 2020-05-31 14:31  楠海  阅读(309)  评论(0编辑  收藏  举报