美文网首页
shell基础

shell基础

作者: 吃可爱长大鸭 | 来源:发表于2019-11-08 11:18 被阅读0次

    shell入门

    什么是shell  壳
         命令解释器  用户输入命令 解释器负责解释给内核 处理后的结果 反馈用户 称为解释
         交互式shell 用户输入命令 解释器解释把处理后的结果反馈给用户的过程称为 交互式
         非交互shell shell执行文本中的命令 当执行到文件的末尾 bash退出
         父shell 不能继承子shell变量  子shell可继承父shell变量
        2)什么是shell脚本
         把可执行命令堆积到一个文本中则称为shell脚本(条件表达式 for循环 if判断等等语句)
    
    shell脚本的书写规范
        1) 目录统一
        2) shell脚本的结尾要以.sh结尾
        3) 脚本的开头需要有解释器 /bin/bash /bin/sh
        4) 脚本中需要有作者信息 #Author lzy date version 做什么的
        5) 脚本每行 或者 一个语句 给一个注释
        6) shell中的文字尽量使用英文 py都是中文
        7) 成对的符号一次性书写完毕 语句
    
    shell执行方式
    1)  系统命令执行
    bash file.sh
    
    2)  全路径执行
    [root@web01 scripts]# chmod +x file.sh 
    [root@web01 scripts]# /server/scripts/file.sh
    
    3). 或者source执行
    [root@web01 scripts]# . file.sh
    [root@web01 scripts]# source file.sh
    
    什么区别?
    1)2 )在子shell中执行
    . source 父进程下执行
    
     环境变量
       1)什么是环境变量?
       右边一堆内容,用一个名字来代替称为环境变量
       name="I am lizhenya"
       如何查看环境变量? 名称的前面加上$
       echo $name
       如何查看系统定义好的环境变量
       env set
       如何取消环境变量?
       unset name
       环境变量(全局变量)  普通变量(局部变量)
       按照生存周期划分
       永久性    修改配置文件 /etc/profile 
       临时性    使用export 变量名称 声明即可
       不加export 只对当前的shell生效
       加export 对当前登录窗口所有的shell生效
       
       环境的相关文件
       1. /etc/profile 开机或者新连接的窗口执行一次
       2. .bashrc
       3. .bash_profile
       4. /etc/bashrc
       2)如何定义环境变量
       变量名=变量值
       环境变量名称的定义      字符 下划线 数字的组合 尽量以字母开头(禁止使用数字开头) 等号两端不允许有空格  见名知其意
       书写方式
       1. OLDBOY_AGE=18     系统中变量的定义格式
       2. oldboy_age=18
       3. oldboy_Age=18   小驼峰语法
       4. Oldboy_Age=18   大驼峰语法
    
     变量值的定义方式
       数字的定义
        oldboy_age=18   连续的数字
       字符串的定义
       name="oldboy"    使用双引号 不知道加什么符号 就加双引号  解析变量
       name='oldboy'    所见即所得  吃什么吐什么
       命令的定义
       time=`date`   反引号  里面必须跟可执行命令
       time=$(date)   $()
       [root@web01 scripts]# name=oldboy
        [root@web01 scripts]# echo "$oldboyisok"
    
        [root@web01 scripts]# echo "${oldboy}isok"
        isok
        [root@web01 scripts]# echo "${name}isok"
        oldboyisok
        [root@web01 scripts]# echo '${name}isok'
        ${name}isok
    重要的特殊位置变量
        $0  脚本的名称,如果全路径执行脚本,则脚本名称也带全路径 basename 获取脚本的名称 重要
            案例: 给用户提示如何使用此脚本
            echo $"Usage: $0 {start|stop|status|restart|force-reload}"
        $n  脚本的第n个参数 $0被脚本名称占用 从$1开始 $9以后 需要加{}
        $#  代表了脚本的传参的总个数  重要
            案例:
            [ $# -ne 2 ] && echo "你请输入两个参数" && exit
        $*  脚本的所有的传参的参数 如果不加双引号则和$@相同 加上双引号则把所有参数视为一个整体
        $@ 脚本的所有的传参的参数 如果不加双引号则和$*相同加上双引号则把所有参数视为独立的参数
           $* 和$@ 正常情况下一样  循环体内不同
        $?  获取上一条命令的结果 0为成功 非0 失败  重要   
        $$  获取脚本的PID
            案例
            服务器运行大量的名称相同的脚本
            echo $$ > /tmp/count.pid
        $!  上一个在后台运行脚本的PID 调试使用
        $_   获取脚本的最后一个参数 相当于ESC .
    
    传参的三种方式
        1)直接传参
        2)赋值传参
        3)read传参
        #第一种传参方式
        echo $1 $2
        #第二种传参方式
        name=$1
        age=$2
        echo $name $age
        read -p "请输入名字和年龄" name1 age1
        echo $name1 $age1
        案例:
        使用read 传参的方式 更改系统的主机名称和IP地址的最后一位 192.168.12.X
        #!/bin/sh
        sdir="/etc/sysconfig/network-scripts/ifcfg-eth0"
        sip=`cat /etc/sysconfig/network-scripts/ifcfg-eth0|awk -F. '/IPADDR/{print $NF}'|cut -c1`
        read -p "请输入主机名称: " name
        hostnamectl set-hostname $name
        read -p "请输入IP地址的最后一位: " ip
        sed -i "s#$sip#$ip#g"  $sdir
        案例:
        sh ping.sh www.baidu.com
        ping www.baidu.com is ok
        sh ping.sh www.xxxxx.com is error
        [root@web01 scripts]# cat ping.sh 
        #!/bin/sh
        read -p "请输入一个网址: " url
        ping -c 1 -W 1 $url >/dev/null 2>&1
        [ $? -eq 0 ] && echo "ping $url is ok" || echo "ping $url is error"
    
    变量的字串知识
        统计变量的长度 重点
    [root@web01 scripts]# echo "I am mazhenkai"|wc -L
    [root@web01 scripts]# name=I am mazhenkai
    [root@web01 scripts]# echo ${#name}
    变量的切片
    [root@web01 scripts]# echo ${name:0:1}
    I
    [root@web01 scripts]# echo ${name:2:2}
    am
    [root@web01 scripts]# echo ${name:0:1}
    I
    [root@web01 scripts]# echo ${name:1}
    am lizhenya
    [root@web01 scripts]# echo ${name:2:5}
    am li
    取字符串长度
    方法1
    echo I am lizhenya teacher I am 18|wc -L
    方法2
    name="I am lizhenya teacher I am 18"
    echo ${#name}
    方法3
    [root@web01 scripts]# expr length "$name"
    29
    方法4
    [root@web01 scripts]# echo $name|awk '{print length}'
    29
    面试题:取字符串长度小于3的
    方法1 
    for循环方式
    [root@web01 scripts]# cat for.sh 
    #!/bin/sh
    for i in I am lizhenya teacher I am 18
    do
    [ ${#i} -lt 3 ] && echo $i
    done
    方法2
    [root@web01 scripts]# echo I am lizhenya teacher I am 18|xargs -n1|awk '{if(length<3)print}'
    I
    am
    I
    am
    18
    方法3
    [root@web01 scripts]# echo I am lizhenya teacher I am 18|awk'{for(i=1;i<=NF;i++)if(length($i)<3)print $i}'
    从前往后删除变量内容
    [root@web01 scripts]# echo $url
    www.sina.com.cn
    [root@web01 scripts]# echo ${url#*.}
    sina.com.cn
    [root@web01 scripts]# echo ${url#*.*.}
    com.cn
    [root@web01 scripts]# echo ${url##*.}
    cn
    从后往前删除变量内容
    [root@web01 scripts]# echo $url
    www.sina.com.cn
    [root@web01 scripts]# echo ${url%.*}
    www.sina.com
    [root@web01 scripts]# echo ${url%%.*}
    www
    变量的替换
    [root@web01 scripts]# echo $url
    www.sina.com.cn
    [root@web01 scripts]# echo ${url/w/a}
    aww.sina.com.cn
    [root@web01 scripts]# echo ${url/w/aa}
    aaww.sina.com.cn
    [root@web01 scripts]# echo ${url/w/a}
    aww.sina.com.cn
    [root@web01 scripts]# echo ${url//w/a}
    aaa.sina.com.cn
    [root@web01 scripts]# echo ${url/sina/baidu}
    www.baidu.com.cn
    
    数值的运算
        1. expr  整数运算
        [root@web01 scripts]# expr 1+1
        1+1
        [root@web01 scripts]# expr oldboy
        oldboy
        [root@web01 scripts]# expr 1 + 1
        2
        [root@web01 scripts]# expr 1 - 1
        0
        [root@web01 scripts]# expr 1 * 11
        expr: 语法错误
        [root@web01 scripts]# expr 1 \* 11
        11
        [root@web01 scripts]# expr 110 / 11
        10
        [root@web01 scripts]# expr 1 + 1.5
        expr: 非整数参数
        案例:  判断传参输入是否为整数
            [root@web01 scripts]# num1=10
            [root@web01 scripts]# num2=11q
            [root@web01 scripts]# expr $num1 + 1 >/dev/null 2>&1
            [root@web01 scripts]# [ $? -ne 0 ] && echo "你输入的是非整数" || echo "你输入的是整数"
            你输入的是整数
            [root@web01 scripts]# expr $num2 + 1 >/dev/null 2>&1
            [root@web01 scripts]# [ $? -ne 0 ] && echo "你输入的是非整数" || echo "你输入的是整数"
            你输入的是非整数
        2. $(())  整数运算 运算效率最高
            [root@web01 scripts]# echo $((10+10))
            20
            [root@web01 scripts]# echo $((10-10))
            0
            [root@web01 scripts]# echo $((10*10))
            100
            [root@web01 scripts]# echo $((10/10))
            1
        3. $[]  整数运算
            [root@web01 scripts]# echo $[10+10]
            20
            [root@web01 scripts]# echo $[10-10]
            0
            [root@web01 scripts]# echo $[10*10]
            100
            [root@web01 scripts]# echo $[10/10]
            1
            [root@web01 scripts]# echo $[10-10.5]
            -bash: 10-10.5: 语法错误: 无效的算术运算符 (错误符号是 ".5")
        4. let  重点
            [root@web01 scripts]# let sum=10+10
            [root@web01 scripts]# echo $sum
            20
            [root@web01 scripts]# num1=100
            [root@web01 scripts]# num2=50
            [root@web01 scripts]# let sum=$num1+$num2
            [root@web01 scripts]# echo $sum
            150
            [root@web01 scripts]# let sum=$num1-$num2
            [root@web01 scripts]# echo $sum
            50
            [root@web01 scripts]# let sum=$num1*$num2
            [root@web01 scripts]# echo $sum
            5000
            [root@web01 scripts]# let sum=$num1/$num2
            [root@web01 scripts]# echo $sum
            2
            i++   变量自增
            [root@web01 scripts]# let i=i+1
            [root@web01 scripts]# echo $i
            1
            [root@web01 scripts]# let i++
            [root@web01 scripts]# echo $i
            2
            [root@web01 scripts]# let i++
            [root@web01 scripts]# let i++
            [root@web01 scripts]# let i++
            [root@web01 scripts]# let i++
            [root@web01 scripts]# echo $i
            6
            [root@web01 scripts]# sh for.sh
            7
            [root@web01 scripts]# sh -x for.sh 
            + for i in I am lizhenya teacher I am 18
            + let a++
            + for i in I am lizhenya teacher I am 18
            + let a++
            + for i in I am lizhenya teacher I am 18
            + let a++
            + for i in I am lizhenya teacher I am 18
            + let a++
            + for i in I am lizhenya teacher I am 18
            + let a++
            + for i in I am lizhenya teacher I am 18
            + let a++
            + for i in I am lizhenya teacher I am 18
            + let a++
            + echo 7
            7
            [root@web01 scripts]# let c++
            [root@web01 scripts]# let c++
            [root@web01 scripts]# let c++
            [root@web01 scripts]# let c++
            [root@web01 scripts]# let c++
            [root@web01 scripts]# let c++
            [root@web01 scripts]# let c++
            [root@web01 scripts]# echo $c
            7
        5.  bc awk python  (bc需要安装) 
            [root@web01 scripts]# echo 10+10|bc
            20
            [root@web01 scripts]# echo 10-10|bc
            0
            [root@web01 scripts]# echo 10*10|bc
            100
            [root@web01 scripts]# echo 10/10|bc
            1
            [root@web01 scripts]# echo 10+10.5|bc
            20.5
            [root@web01 scripts]# awk 'BEGIN{print 10+10}'
            20
            [root@web01 scripts]# awk 'BEGIN{print 10-10}'
            0
            [root@web01 scripts]# awk 'BEGIN{print 10/10.5}'
            0.952381
            [root@web01 scripts]# awk 'BEGIN{print 10*10.5}'
            105
            [root@web01 scripts]# awk 'BEGIN{print 10^10.5}'
            3.16228e+10
            [root@web01 scripts]# awk 'BEGIN{print 10^10}'
            10000000000
            [root@web01 scripts]# echo 100 200
            100 200
            [root@web01 scripts]# echo 100 200|awk '{print $1+$2}'
            300
    
            [root@web01 scripts]# python
            Python 2.7.5 (default, Oct 30 2018, 23:45:53) 
            [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)] on linux2
            Type "help", "copyright", "credits" or "license" for more information.
            >>> 10+10
            20
            >>> 10-10
            0
            >>> 10*10
            100
            >>> 10/10
            1
            >>> 10/10.5
            0.9523809523809523
            >>> 
    小结  expr $(()) $[] let bc awk python
            案例1:
            ps axu 中的VSZ 列 所有的数相加 得出结果
            [root@web01 scripts]# ps axuf|awk '{print $5}'|grep -v VSZ|tr "\n" "+"|sed -r 's#(.*)#\10\n#g'|bc
            12778952
            案例2:
            做一个加减乘除的计算器
            例如:
            请输入第一个数字 10
            请输入第二个数字 20
            显示的结果  10+20=30
            
            [root@web01 scripts]# cat count.sh 
            #!/bin/sh
            read -p "请输入第一个数字: " num1
            read -p "请输入第二个数字: " num2
            echo "$num1+$num2=$[$num1+$num2]"
            echo "$num1-$num2=$[$num1-$num2]"
            echo "$num1*$num2=$[$num1*$num2]"
            echo "$num1/$num2=$[$num1/$num2]"
            
    13. 条件表达式
        []======test   []常用
        [ -f file ] 文件是否存在 且为普通文件 重点
        [ -e file ] 文件存在则为真
        [ -d file ] 目录存在则为真         重点
        [ -x file ] 文件有执行权限则为真
        [ -w file ]  文件可写则为真
        [ -r file ]  文件可读则为真
        [root@web01 scripts]# [ -f /etc/hosts ] && echo 为真 || echo 为假
        为真
        [root@web01 scripts]# [ -f /etc/hostsss ] && echo 为真 || echo 为假
        为假
        [root@web01 scripts]# [ -d /etc/hosts ] && echo 为真 || echo 为假
        为假
        [root@web01 scripts]# [ ! -d /etc/hosts ] && echo 为真 || echo 为假
        为真
        [root@web01 scripts]# [ -e /etc/hosts ] && echo 为真 || echo 为假
        为真
        [root@web01 scripts]# [ -e /etc/ ] && echo 为真 || echo 为假
        为真
        [root@web01 scripts]# [ -r /etc/ ] && echo 为真 || echo 为假
        为真
        [root@web01 scripts]# [ -w /etc/ ] && echo 为真 || echo 为假
        为真
        [root@web01 scripts]# [ -x /etc/ ] && echo 为真 || echo 为假
        为真
        [root@web01 scripts]# [ -x /etc/hosts ] && echo 为真 || echo 为假
        [root@web01 scripts]# [ -x /etc/hosts ] && echo 为真 || echo 为假
        为假
        [root@web01 scripts]# [ -x /etc/hosts ] && echo 为真 || echo 为假
        为假
        [root@web01 scripts]# ll
        总用量 24
        -rw-r--r-- 1 root root 230 8月   1 16:07 count.sh
        -rw-r--r-- 1 root root  74 8月   1 15:33 for.sh
        -rw-r--r-- 1 root root 297 7月  31 16:59 ip.sh
        -rw-r--r-- 1 root root  14 8月   1 15:06 oldboy.sh
        -rw-r--r-- 1 root root 152 7月  31 17:12 ping.sh
        -rwxr-xr-x 1 root root 225 7月  31 16:34 test.sh
        [root@web01 scripts]# [ -x test.sh ] && echo 为真 || echo 为假
        为真
    
        -f 判断文件是否存在
        案例:
        [root@web01 scripts]# [ -f /etc/init.d/functions ] && . /etc/init.d/functions
        [root@web01 scripts]# action "hehehe is"  /bin/true
        hehehe is                                                  [  确定  ]
        [root@web01 scripts]# action "hehehe is"  /bin/false
        hehehe is                                                  [失败]
        函数库使用
        [root@web01 scripts]# cat ping.sh 
        #!/bin/sh
        [ -f /etc/init.d/functions ] && . /etc/init.d/functions
        read -p "请输入一个网址: " url
        ping -c 1 -W 1 $url >/dev/null 2>&1
        [ $? -eq 0 ] && action "ping $url is" /bin/true || action "ping $url is" /bin/false
    
        -d 判断是否为目录 目录是否存在
        [root@web01 scripts]# [ -d /alex ] || mkdir /alex
        [root@web01 scripts]# test -f /etc/hosts && echo ok || echo error
        ok
        [root@web01 scripts]# test -d /etc/hosts && echo ok || echo error
        error
        [root@web01 scripts]# test -d /etc/ && echo ok || echo error
        ok
    
    
    14. 数值的比较
        [ 数值1 比较符 数值2 ]     [[]] = != >=  < <=
        -eq   相等
        -ne   不等于
        -gt   大于
        -ge   大于等于
        -lt   小于
        -le   小于等于
        [root@web01 scripts]# [ 10 -eq 10 ] && echo ok || echo error
        ok
        [root@web01 scripts]# [ 10 -gt 10 ] && echo ok || echo error
        error
        [root@web01 scripts]# [ 10 -ge 10 ] && echo ok || echo error
        ok
        [root@web01 scripts]# [ 10 -ne 10 ] && echo ok || echo error
        error
        [root@web01 scripts]# [ 10 -lt 10 ] && echo ok || echo error
        error
        [root@web01 scripts]# [ 10 -le 10 ] && echo ok || echo error
        ok
        案例:
        统计当前磁盘的使用率 如果大于5% 则把内容写入到以日期为名称的文本中 2019-08-01.txt
        如果小了 则把当前的使用率 写入 2019-08-01.txt
        1.如何取出当前的使用率
          df -h|awk 'NR==2{print $(NF-1)}'
          df -h|grep /$|awk '{print $(NF-1)}'
        
        2.条件表达式 整数的比较
        3.输出结果到文本
        4.调试
        [root@shell scripts]# cat usedisk.sh 
        #!/bin/sh
        time=`date +%F`
        usedisk=`df -h|grep /$|awk '{print $(NF-1)}'`
        [ ${usedisk%\%} -gt 5 ] && echo "当前使用率不正常 $usedisk" >> ${time}.txt || echo "当前使用率正常 $usedisk" >> ${time}.txt 
        [root@web01 scripts]# [ `df -h|grep /$|awk -F "[ %]+" '{print $(NF-1)}'` -gt 5 ] && echo error || echo ok
        error
        [root@web01 scripts]# [ `df -h|grep /$|awk -F "[ %]+" '{print $(NF-1)}'` -gt 80 ] && echo error || echo ok
        ok
        案例:
        统计系统内存的使用率 如果大于10则 echo 使用率到 以时间命名的文件中
        1.如何取出当前的使用率
          百分比=====使用的除总数乘100
        2.条件表达式 整数的比较
        3.输出结果到文本
        4.调试
        [root@web01 scripts]# free|awk 'NR==2{print $3/$2*100}'
        19.0124
        [root@web01 scripts]# free=`free|awk 'NR==2{print $3/$2*100}'`
        [root@web01 scripts]# [ ${free%.*} -gt 10 ] && echo error || echo ok
        error
        [root@web01 scripts]# [ ${free%.*} -gt 80 ] && echo error || echo ok
        ok
        案例:
        统计系统的负载 负载超过2 则发送到文件中 否则提示正常
        1.如何查看统计负载
        2.取值做比较
        3.输出结果
        4.调试
    小结: 数值运算 expr $(()) $[] let bc awk python
          表达式
          -f -e -d -r -w -x
          数值的比较
          -gt -ne -eq -ge -lt -le
          案例
        
        作业:
        使用脚本统计 主机名称 网卡IP地址 虚拟平台 系统版本号 外网IP地址 磁盘使用率
        例如
        sh os.sh
        当前系统的主机名称是 web01
        当前系统的IP地址是 10.0.0.7
        
    
    15.字符串比对
        字符串必须使用双引号
        [ "name" = "name" ] 
        [ "name" != "name" ] 
        [root@web ~]# [ "$USER" = "root" ]
        [root@web ~]# echo $USER
        root
        [root@web ~]# [ "$USER" = "root" ]
        [root@web ~]# echo $?
        0
        [root@web ~]# [ "$USER" = "alex" ]
        [root@web ~]# echo $?
        1
        [root@web ~]# [ "$USER" != "alex" ]
        [root@web ~]# echo $?
        0
        -z  -n
        [root@web ~]# name=""
        [root@web ~]# [ -z $name ]
        [root@web ~]# echo $?
        0
        [root@web ~]# [ ! -z $name ]
        [root@web ~]# echo $?
        1
        [root@web ~]# name="alex"
        [root@web ~]# [ -z $name ]
        [root@web ~]# echo $?
        1
        [root@web ~]# [ -n $name ]
        [root@web ~]# echo $?
        0
        -z 案例:
        read -p "请输入名字" name1 
        [ -z $name1 ] && echo "请输入姓名否则不继续执行" && exit
        read -p "请输入年龄" age1
        echo $name1 $age1
    
        正则比对
        [[]]
        [root@web01 scripts]# [ "$USER" = "root" ]
        [root@web01 scripts]# echo $?
        0
        [root@web01 scripts]# [[ "$USER" =~ ^r ]]
        [root@web01 scripts]# echo $?
        0
        [root@web01 scripts]# [[ "$USER" =~ t$ ]]
        [root@web01 scripts]# echo $?
        0
        [root@web01 scripts]# [[ ! "$USER" =~ t$ ]]
        [root@web01 scripts]# echo $?
        1
        判读传参的参数是否为整数
        方法1
        [root@web01 scripts]# age=188
        [root@web01 scripts]# 
        [root@web01 scripts]# 
        [root@web01 scripts]# [[ "$age" =~ ^[0-9]+$ ]]
        [root@web01 scripts]# echo $?
        0
        [root@web01 scripts]# age=188q
        [root@web01 scripts]# [[ "$age" =~ ^[0-9]+$ ]] && echo $?
        [root@web01 scripts]# [[ "$age" =~ ^[0-9]+$ ]] || echo $?
        1
        [root@web01 scripts]# age=18.8
        [root@web01 scripts]# [[ "$age" =~ ^[0-9]+$ ]]
        [root@web01 scripts]# echo $?
        1
        方法2
        expr $1 + 0 >/dev/null 2>&1
        [ $? -ne 0 ] && exit
        
        
    16.多整数比对
        -a  and
        -o  or
        [ 10 -eq 10 -a 100 -ne 100 ]
        [root@web01 scripts]# [ 10 -eq 10 -a 100 -ne 100 ]
        [root@web01 scripts]# echo $?
        1
        [root@web01 scripts]# [ 10 -eq 10 -a 100 -eq 100 ]
        [root@web01 scripts]# echo $?
        0
        [root@web01 scripts]# [ 10 -eq 10 -o 100 -ne 100 ]
        [root@web01 scripts]# echo $?
        0
    
        [root@web01 scripts]# [[ 10 -eq 10 && 100 -ne 100 ]]
        [root@web01 scripts]# [[ 10 -eq 10 -a 100 -ne 100 ]]
        -bash: 条件表达式中有语法错误
        -bash: `-a' 附近有语法错误
        [root@web01 scripts]# [[ 10 -eq 10 && 100 -ne 100 ]]
        [root@web01 scripts]# echo $?
        1
        [root@web01 scripts]# [[ 10 -eq 10 || 100 -ne 100 ]]
        [root@web01 scripts]# echo $?
        0
        案例:
        传入两个数字 比对两个数字的大小 
        例如 
        sh count.sh 10 10       要求判读是否传入两个参数 要求数字加判读是否为整数(禁止if)
        10=10
        #!/bin/sh
        [ $# -ne 2 ] && echo "please input two number" && exit
        [[ ! $1 =~ ^[0-9]+$ ]] && echo "请输入整数" && exit 50
        [[ ! $2 =~ ^[0-9]+$ ]] && echo "请输入整数" && exit 100
        [ $1 -eq $2 ] && echo "$1=$2"
        [ $1 -gt $2 ] && echo "$1>$2"
        [ $1 -lt $2 ] && echo "$1<$2"
        案例:批量创建用户 批量创建10个用户 oldboy1 oldboy2 oldboy3...oldboy10
            要求密码统一设置为123456
            1.输入用户的前缀  oldboy
              判断如果为空 则退出
            2.输入需要创建用户的个数 10
              判断是否为整数
            [root@web01 scripts]# cat useradd.sh
            #!/bin/sh
            #read -p "please input prefix: " name
            #read -p "创建的个数: " num
            for i in {1..10}
            do
                echo oldboy$i
            done
    
            [root@web01 scripts]# cat useradd.sh 
            #!/bin/sh
            read -p "please input prefix: " name
            read -p "创建的个数: " num
            for i in `seq $num`
            do
                useradd $name$i >/dev/null 2>&1
                echo 123456|passwd --stdin $name$i &>/dev/null
                [ $? -eq 0 ] && echo "$name$i create is ok"
            done
            案例:
            判断当前10.0.0.0/24网络中 有哪些IP地址在线 ping通则在线
            [root@web01 scripts]# cat ping.sh 
            #!/bin/sh
            [ -f /etc/init.d/functions ] && . /etc/init.d/functions
            for i in `seq 254`
            do
                { IP=10.0.0.$i
                ping -c 1 -W 1 $IP >/dev/null 2>&1
                [ $? -eq 0 ] && action "ping $IP is" /bin/true
                } &
            done
    
            --------
            10.0.0.1-254都通  网卡可配置多个IP
            
            网络相关
            ip addr add 10.0.0.3/24 dev eth0  临时生效 重启失效
            面试题 配置一条默认网关
            route add default gw 10.0.0.254
            删除网关
            route add default gw 10.0.0.254
            其他方法 静态路由方式
            ip route add 0/0 via 10.0.0.254
            策略路由
            服务器使用vpn常用 网关被替换成vpn
            pptpstup 拨号命令
            查看网关
            route -n
            开机启动配置文件(/etc/rc.local) +x 权限 rc.d/rc.local  (禁止使用alias和变量)
    
    17.if判断
        单分支
        if [你有房];then       [ -f file ] && echo ok
        
        if [你有房]
        then
            我就嫁给你
        fi
    
        双分支
        if [ 你有房 ]          [ -f file ] && echo ok || echo error
        then
            我就嫁给你
        else
            拜拜
        fi
        
        多分支
        if [ 你有房 ]
        then
            我就嫁给你
        elif [ 你有钱 ]
        then
            我也嫁给你
        elif [ 你爸是李刚 ]
        then
            我也嫁给你
        elif [ 活好!运维技术好 ]
        then
            我倒贴也嫁给你
        elif [ 你在老男孩学运维 ]
        then
            我考虑考虑
        else
            拜拜
        fi
            
        案例: 输入两个数字 是否为整数 使用if方式 
        #!/bin/bash
        read -p "请输入第一个数字:" num1
        read -p "请输入第二个数字:" num2
        if [ -z $num1 ]
        then
           echo "您输入的第一个数字为空"&& exit
        elif [ -z $num2 ]
        then
           echo "您输入的第二个数字为空"&& exit
        elif [[  "$num1" =~ ^[0-9]+$ && "$num2" =~ ^[0-9]+$ ]]
        then
         
        if [ $num1 -lt $num2 ]
        then
           echo "$num1<$num2"
        elif [ $num1 -gt $num2 ]
        then
           echo "$num1>$num2"
        else
           echo "$num1=$num2"
        fi
    
        else
            echo "您输入了错误的值!"&& exit
        fi    
            
        案例: 根据操作系统不同的版本安装不同的源
            1. 如何取出版本号
            2. 如何做版本号的比对
            3. 比对完成执行相对应的安装源
        [root@web scripts]# cat yum.sh 
        #!/bin/sh
        ve=`cat /etc/redhat-release |awk '{print $(NF-1)}'`
        #centos6.x使用以上命令获取不到版本号
        if [ ${ve%%.*} -eq 7 ]
        then
            #判断网络是否通畅ping 如果不通 则重启systemctl restart network 通继续执行
            mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
            #测试wget是否已安装 无安装先安装wget
            wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
        elif [ ${ve%%.*} -eq 6 ]
        then
            mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
            wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
        fi
        
        作业:安装Centos6.x
            
        案例:猜数字  笔试题
        生成一个随机数1-100之间
        RANDOM 随机数的范围 0-32767
        取余
        echo $((RANDOM%100+1))
        用户输入一个数字
        判断用户输入的数字如果相等则退出提示猜对了 大了 提示比随机数大  小了 提示 比随机数小
            
        [root@web scripts]# cat ran.sh 
        #!/bin/sh
        ran=`echo $((RANDOM%100+1))`
        while true
        do
            let i++
        read -p "请输入一个数字[1-100]: " num
        if [ $num -gt $ran ];then
            echo "你输入的数字大了"
        elif [ $num -lt $ran ];then
            echo "你输入的数字小了"
        else
            echo "恭喜你猜对了 总共猜了 $i 次"
            exit
        fi
        done
        案例: 反向破解RANDOM  字符串比较
        [root@web scripts]# echo $RANDOM
            6500
            [root@web scripts]# echo $RANDOM|md5sum|cut -c1-8
            98f23d45
            [root@web scripts]# echo 1|md5sum 
            b026324c6904b2a9cb4b88d6d61c81d1  -
            [root@web scripts]# echo 1|md5sum |cut -c1-8
            b026324c
            [root@web scripts]# echo $RANDOM|md5sum|cut -c1-8
            abafad14
            [root@web scripts]# echo $RANDOM|md5sum|cut -c1-8
            312c404c
            [root@web scripts]# echo $RANDOM|md5sum|cut -c1-8
            02ab2b9b
            [root@web scripts]# echo $RANDOM|md5sum|cut -c1-8
            ab1e7ee2
            [root@web scripts]# echo 1|md5sum |cut -c1-8
            b026324c
    
            6的虚拟机 版本号--yum源  RANDOM反向破解 练习题
    RANDOM  0-32767
            3ab11dfb
            ae87e18e
            782c52c9
            38741e97
            2699874
            
    if判断
    单分支  一个条件  一个结果
    双分支  一个条件  两个结果     
    多分支  多个条件  多个结果
            
    18. case 流程控制语句
        
        case 变量名4 in
                    模式匹配1)
                        命令的集合
                            ;;
                    模式匹配2)
                        命令的集合
                            ;;
                    模式匹配3)
                        命令的集合
                            ;;
                    *)                  *的下一行不需要有;;
                    echo USAGE[$0 1|2|3]
        esac
                    
        [root@web scripts]# cat case.sh 
        #!/bin/sh
        case $1 in
            Linux)
                 echo linux......
                 ;;
            Shell)
                 echo Shell......
                 ;;
            MySQL)
                 echo MySQL.....
                 ;;
               *)
                echo "USAGE $0 [Linux|Shell|MySQL]"
        esac
        
        case 批量删除用户
        [root@web scripts]# cat casedel.sh
        #!/bin/sh
        read -p "请输入用户名前缀: " prefix
        read -p "请输入要删除几个用户: " num
        for i in `seq $num`
        do
            echo $prefix$i
        done
        read -p "你确定要删除以上用户吗?[y|yes|YES|n|N|no]" ready
    
        for n in `seq $num`
        do
            name=$prefix$n
        case $ready in
             y|yes|YES)
                  id $name &>/dev/null
                  if [ $? -eq 0 ];then
                  userdel -r $name
                   [ $? -eq 0 ] && echo "$name del is ok"
                  else
                  echo "id: $name: no such user"
                  fi
                  ;;
            n|N|no)
                echo "不删除我玩啥呢?" && exit
                ;;
                 *)
                echo "USAGE $0 [y|yes|YES|n|N|no]"
    
        esac
        done
        菜单
        [root@web scripts]# cat menu.sh
        #!/bin/sh
        echo -e "\t\t#########################"
        echo -e "\t\t#\t1.系统负载\t#"
        echo -e "\t\t#\t2.磁盘使用率\t#"
        echo -e "\t\t#\t3.内存使用率\t#"
        echo -e "\t\t#\t4.当前登录用户\t#"
        echo -e "\t\t#\t5.当前eth0的IP\t#"
        echo -e "\t\t#\t6.显示菜单\t#"
        echo -e "\t\t#########################"
        menu(){
        cat<<EOF
                1.u 系统负载
                2.d 磁盘使用率
                3.f 内存使用率
                4.w 当前登录用户
                5.ip 当前eth0的IP
                6.h 显示帮助(菜单)
                7.q 退出
        EOF
        }
        menu
        while true
        do
        read -p "请输入你想要查看的系统信息的编号: " num
        case $num in
               1|u)
                uptime
                ;;
               2|d)
                df -h
                ;;
               3|f)
                free -h
                ;;
               4|w)
                w
               ;;
               5|ip)
               ip add
               ;;
               6|h)
                clear
                menu
                ;;
               7|q)
                  exit
                  ;;
               *)
                menu
        esac
        done
    
        菜单显示以下内容
        1.包子 
        2.馒头 
        3.套餐
        4.宫保鸡丁  
        5.鱼香肉丝 
        6.牛欢喜 
        7.麻辣香锅
        8.酸菜鱼 
        9.撸串
        10.不吃了
        随机产生一个 你中午要吃什么
        RAN=`echo $((RANDOM10+1))`
        case $RAN in
                   1)
                    echo "你抽取到的序号是$RAN所以你中午要吃的是包子"
        esac  
        案例:
        Nginx 启动脚本 jumpserver跳板机
        /usr/sbin/nginx     使用命令进行启动后 systemctl 无法管理命令行启动的Nginx
        
        /usr/sbin/nginx 启动
        /usr/sbin/nginx -s stop 停止
        /usr/sbin/nginx -s reload 重新加载\
        
        /usr/sbin/nginx -s stop   重启
        sleep 2
        /usr/sbin/nginx
        自取状态  PID  端口    状态
        [root@web scripts]# sh nginxstart.sh status
        当前Nginx的PID:116528
        [root@web scripts]# cat nginxstart.sh 
        #!/bin/sh
        . /etc/init.d/functions
        en=$1
        fun(){
        [ $? -eq 0 ] && action "Nginx $en is" /bin/true || action "Nginx $en is" /bin/false
        }
        case $1 in
             start)
                 /usr/sbin/nginx
                fun
                 ;;
             stop)
                /usr/sbin/nginx -s stop
                fun
                 ;;
            reload)
                /usr/sbin/nginx -s reload
                fun
                ;;
            restart)
                /usr/sbin/nginx -s stop
               sleep 2
               /usr/sbin/nginx
                fun
               ;;
            status)
                echo "当前Nginx的PID:`ps axu|grep nginx|grep master|awk '{print $2}'`"
               ;;
               *)
               echo "USAGE $0 [start|stop|reload|restart|status]"
        esac
        jumpserver 跳板机
        WEB01=10.0.0.7
        WEB02=10.0.0.8
        MySQL=10.0.0.51
        NFS=10.0.0.31
        菜单
            1. WEB01=10.0.0.7
            2. WEB02=10.0.0.8
            3. MySQL=10.0.0.51
            4. NFS=10.0.0.31
            ...
        read -p 请输入连接服务器的编号或者是主机名 : num
        case $num in
                    1|WEB01)
                           ssh root@$WEB01  免秘钥登录
        esac
        
        [root@web scripts]# cat jumpserver.sh 
        #!/bin/sh
        WEB01=10.0.0.7
        WEB02=10.0.0.8
        MySQL=10.0.0.51
        NFS=10.0.0.31
        menu(){
        cat<<EOF
                1. WEB01=10.0.0.7
                2. WEB02=10.0.0.8
                3. MySQL=10.0.0.51
                4. NFS=10.0.0.31
                5|h. 显示菜单
        EOF
        }
        menu
        trap "echo 不要乱输入!小心爆炸!" HUP INT TSTP
        while true
        do
        read -p "请输入连接服务器的编号或者是主机名 :" num
        case $num in
                        1|WEB01)
                               ssh root@$WEB01 # 免秘钥登录
                        ;;
                        2|WEB02)
                            ssh root@$WEB02 # 免秘钥登录
                                        ;;
                        5|h)
                            clear
                            menu
                        ;;
                        woshiyunwei)
                            exit
                        ;;
                         *)
                echo "USAGE:[WEB01|1|WEB02|2|h]"
        esac
        done
        
    19. for循环
        for 变量名 in [取值列表] 苹果 香蕉 梨 桃子 西瓜  字符串 数字{}序列  命令
        do
              命令体
              echo 呵呵
        done
    
        案例:使用for循环创建用户
        cat user.txt
        zs
        ls
        em
        oldboy
        [root@web scripts]# cat for1.sh 
        #!/bin/sh
        for i in `cat user.txt`
        do
            useradd $i
        done
    
        命令行中使用for循环批量删除用户
        for i in `cat user.txt`;do userdel -r  $i;done
        
    
        案例2:笔试题
        使用for循环 从1加到100  结果5050
    
        seq -s + 100|bc
        
        [root@web scripts]# cat ping.sh 
        #!/bin/sh
        [ -f /etc/init.d/functions ] && . /etc/init.d/functions
        for i in `seq 254`
        do
             IP=10.0.0.$i
            ping -c 1 -W 1 $IP >/dev/null 2>&1
            [ $? -eq 0 ] && action "ping $IP is" /bin/true
        done
    
        for i in `seq 100`;do sum=$[sum+i];done;echo $sum
    
    20. while循环
        while [ 条件表达式 ]
        do
            命令
        done
    
        案例:
        1加到100
        #!/bin/sh
        i=0
        while [ $i -le 100 ]
        do
            sum=$[i+sum]
            let i++
        done
        echo $sum
        while read line     line 变量名  按行读取文件的内容  for循环是按照空格分隔读取文件内容
        do
            命令
        done<user.txt
        [root@web scripts]# cat while3.sh 
        #!/bin/sh
        . /etc/init.d/functions
        while read line
        do
            user=`echo $line|awk '{print $1}'`
            useradd $user
            pass=`echo $line|awk '{print $2}'`
            echo $pass|passwd --stdin $user &>/dev/null
            [ $? -eq 0 ] && action "$user create is ok" /bin/true
        done<user.txt
        判断一个文件中总共的行数
        统计行号
        
        [root@web scripts]# cat while4.sh
        #!/bin/sh
        while read line
        do
            let i++
        done</etc/passwd
        echo $i
        
        
        
        
        
    志气----理想----(村里--小别墅--种点花花草草--绿色蔬菜--养金毛二哈--几只猫--台球桌--锻炼器材--做饭--野泳--农场) 
        志  目标
        气  持续不断的努力
        
    
    21. 流程控制语句 exit continue break
        exit  退出整个脚本 不会继续执行
        break 跳出本次循环 继续往下执行 跳出循环体
        continue 结束当前此次的命令,继续下一次循环
        
        [root@web scripts]# cat exit.sh break.sh continue.sh 
        #!/bin/sh
        while true
        do
            echo ok
            exit
            echo hehe
        done
        echo done......
        #!/bin/sh
        while true
        do
            echo ok
            break 
            echo hehe
        done
        echo done......
        #!/bin/sh
        while true
        do
            echo ok
            continue
            echo hehe
        done
        echo done......
            
        案例2:
        #!/bin/sh
        for i in `seq 10`
        do
            user=oldboy$i
            id $user &>/dev/null
            if [ $? -ne 0 ];then
               useradd $user
               [ $? -eq 0 ] && echo "$user create is ok"
            else
                break
            fi
        done
        echo hehe.......
    
        
        #!/bin/sh
        for i in `seq 10`
        do
            user=oldboy$i
            id $user &>/dev/null
            if [ $? -ne 0 ];then
               useradd $user
               [ $? -eq 0 ] && echo "$user create is ok"
            else
                continue
            fi
        done
        echo hehe.......
        
    22. 函数
        命令的集合 完成特定功能的代码块
        模块化 复用
        函数和变量类似 只有先定义才可以调用,如果只定义不调用 则不会执行
        
        函数的定义和调用
        三种方法
        [root@web scripts]# cat fun.sh 
        #!/bin/sh
        test1(){
            echo "第一种函数定义方式"
        }
        function test2(){
            echo "第二种函数定义方式"
        }
        function test3 {
            echo "第三种函数定义方式"
        }
        test1
        test2
        test3
    
        函数的传参 不能直接传参
        1. 在函数名的后面跟参数
        2. 全局配置 在函数的最上面 设置变量
        3. local    只在函数体内部生效
        fun(){
            if [ -f $1 ];then
                echo "$1 is exsis"
            else
                echo "$1 is no ex"
            fi
        }
        fun $1
        
        [root@web scripts]# cat fun.sh 
        #!/bin/sh
        fun(){
              if [ -f $1 ];then
              echo "$1 exists"
              else
              echo "$1 no exists"
              fi
        }
        fun $2 $3
    
        
        #!/bin/sh
        fun(){
        num=20
        for i in `seq 10`
        do
                sum=$[num+i]
        done
            echo $sum
        }
        fun
    
        [root@web scripts]# cat fun1.sh
        #!/bin/sh
        fun(){
        num=20
        for i in `seq $1`
        do
            sum=$[num+i]
        done
            echo $sum
        }
        fun $3 $1 $2
        
        [root@web scripts]# cat fun1.sh 
        #!/bin/sh
        fun(){
        num=20
        for i in `seq $1`
        do
            sum=$[num+i]
        done
            echo $sum
        }
        fun $1
        echo $num
        以下错误 先定义 在调用
        [root@web scripts]# cat fun1.sh
        #!/bin/sh
        fun $1
        fun(){
        num=20
        for i in `seq $1`
        do
            sum=$[num+i]
        done
            echo $sum
        }
        函数的返回值 return
        
        #!/bin/sh
        [ -f /etc/hosts ] && exit 50 || exit 100
        
        #!/bin/sh
        fun(){
            if [ -f $1 ];then
                return 50
             else
                return 100
             fi
        }
        fun $1
        re=$?
        [ $re -eq 50 ] && echo "$1 该文件存在"
        [ $re -eq 100 ] && echo "$1 该文件不存在"
    
        [root@web scripts]# cat fun3.sh 
        #!/bin/sh
        fun(){
            if [ -f $1 ];then
            return 50
             else
            return 100
             fi 
        }
        fun $1
        if [ $? -eq 50 ];then
            echo "ok"
        else
            echo "error"
        fi
        函数内如果执行的上一条是函数名  则不会返回函数本身执行的返回值
        [root@web scripts]# cat fun4.sh
        #!/bin/sh
        fun(){
           echo 50
           return 1
        }
        re=`fun`
        echo "函数的返回值是?: $?"
        echo "函数执行的结果是?: $re"
        [root@web scripts]# sh fun4.sh
        函数的返回值是?: 1
        函数执行的结果是?: 50
    
        --------------------------
        [root@web scripts]# cat fun4.sh
        #!/bin/sh
        fun(){
           echo 50
           return 1
        }
        re=`fun`
        name=oldboy
        echo "函数的返回值是?: $?"
        echo "函数执行的结果是?: $re"
        [root@web scripts]# sh fun4.sh
        函数的返回值是?: 0
        函数执行的结果是?: 50
    
    
    

    相关文章

      网友评论

          本文标题:shell基础

          本文链接:https://www.haomeiwen.com/subject/efsibctx.html