美文网首页
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