zoukankan      html  css  js  c++  java
  • CenOS shell脚本

    1、先查看脚本解释器

    [es@bigdata-senior01 ~]$ echo $SHELL
    /bin/bash

    2、编写最简单的脚本

    vi test.sh
    #第一行的脚本声明(#!)用来告诉系统使用哪种 Shell 解释器来执行该脚本 #!/bin/bash #查看当前目录,按文件大小列出文件 pwd ls -lSh
    Shell 脚本文件的名称可以任意,但为了避免被误以为是普通文件,将.sh 后缀加上,以表示是一个脚本文件。

    3、执行脚本的方式

    第一种:用解释器执行,sh/bash或都可以,用subshell方式开打
    [es@bigdata-senior01 ~]$ bash test.sh 
    
    第二种:通过./方式直接执行,用subshell方式开打,需要有“执行权限”,通过chmod来添加
    [es@bigdata-senior01 ~]$ ./test.sh

    第三种:用source来执行,在当前shell内去读取,变量会被设置到当前shell环境中
    [es@bigdata-senior01 ~]$ source test.sh
    source可以省略为"."
    [es@bigdata-senior01 ~]$ . test.sh #注意.后面有空格




    注意:第二种方式如果出现权限不足的情况,那么注意看看文件有没有执行权限

    [es@bigdata-senior01 ~]$ ./test.sh
    -bash: ./test.sh: 权限不够
    
    因为test.sh没有执行权限,我们查看一下
    [es@bigdata-senior01 ~]$ ll test.sh 
    -rw------- 1 es es 167 1月   8 15:25 test.sh
    没有x,没有执行权限,所以加一下就可以 [es@bigdata-senior01 ~]$ chmod 700 test.sh 如果要给所有人权限 [es@bigdata-senior01 ~]$ chmod 777 test.sh

    4、脚本参数,例如:./test02.sh one two three four five

    $0 表示当前 Shell 脚本程序的名称
    $# 表示总共有几个参数
    $* 表示所有位置的参数值
    $? 表示shell返回值
    $1、$2、$3……则分别对应着第 N 个位置的参数值

    用例

    [es@bigdata-senior01 ~]$ cat test02.sh
    #!/bin/bash
    echo "脚本名称:$0"
    echo "脚本共有参数$#个"
    echo "脚本参数:$*"
    echo "脚本第一个参数:$1"
    echo "脚本第三个参数:$3"
    
    [es@bigdata-senior01 ~]$ bash test02.sh one two three four five
    脚本名称:test02.sh
    脚本共有参数5个
    脚本参数:one two three four five
    脚本第一个参数:one
    脚本第三个参数:three

    5、条件测试,Shell 脚本中的条件测试语法可以判断表达式是否成立,若条件成立则返回数字 0,否则便返回其他随机数值。

    [ 条件表达式 ] #注意表达式两端各有一个空格

    5.1 文件测试:

    -d  测试文件是否为目录类型 
    -e  测试文件是否存在 
    -f  判断是否为一般文件 
    -r  测试当前用户是否有权限读取 
    -w  测试当前用户是否有权限写入 
    -x  测试当前用户是否有权限执行 

    用例:

    判断test02.sh是否是目录,结果非0,为不符合
    这个判断原则其实与程序(列入java程序)退出代码一致,退出代码为0表示正常退出,退出代码>0就是异常退出 [es@bigdata-senior01 ~]$ [ -d test02.sh ] [es@bigdata-senior01 ~]$ echo $? 1

    判断test02.sh是否是文件,结果为0,符合
    [es@bigdata-senior01 ~]$ [ -f test02.sh ]
    [es@bigdata-senior01 ~]$ echo $?
    0

    5.2 逻辑与(&&),在 Shell终端中逻辑“与”的运算符号是&&,它表示当前面的命令执行成功后才会执行它后面的命令

    [es@bigdata-senior01 ~]$ [ -f test02.sh ] && echo "ok"
    ok

    5.3 逻辑或(||),表示当前面的命令执行失败后才会执行它后面的命令

    [es@bigdata-senior01 ~]$ [ -d test02.sh ] || echo "不是目录"
    不是目录

    [es@bigdata-senior01 ~]$ [ $USER = 112 ] && echo "用户是es" || echo "用户不是es"
    用户不是es
    [es@bigdata-senior01 ~]$ [ $USER = es ] && echo "用户是es" || echo "用户不是es"
    用户是es

    5.4 逻辑“非”(!),在 Linux系统中的运算符号是一个叹号(!),它表示把条件测试中的判断结果取相反值

    [es@bigdata-senior01 ~]$ [ ! $USER = es ] && echo "用户是es" || echo "用户不是es"
    用户不是es

     6、整数比较运算符,因为=,<,>这些符号和赋值以及重定向冲突,所以shell脚本中,整数比较使用英文简写来代替的

    -eq  是否等于
    -ne  是否不等于
    -gt  是否大于
    -lt  是否小于
    -le  是否等于或小于
    -ge  是否大于或等于

    用例:

    取空闲内存:
    [es@bigdata-senior01 ~]$ freeMem=$(free -m | grep Mem | awk '{print $4}')
    或者
    [es@bigdata-senior01 ~]$ freeMem2=`free -m | grep Mem | awk '{print $4}'`
    
    [es@bigdata-senior01 ~]$ [ $freeMem -lt 1024 ] && echo "内存不足" || echo "内存正常"
    内存正常
    [es@bigdata-senior01 ~]$ echo $freeMem
    1552

    7、字符串比较,只有等于、不等于、空等。

    =  比较字符串内容是否相同
    !=  比较字符串内容是否不同
    -z  判断字符串内容是否为空
    [es@bigdata-senior01 ~]$ [ $LANG != "zh_CN.UTF-8" ] && echo "需要中文字符集" || echo "是中文字符集"
    是中文字符集

    8、流程控制,if、for、while、case等

    8.1 if条件

    语法:
    if 条件
        then 命令1
    else 命令2 fi 结束if

    语法2:
    if 条件 then 命令1
    elif 条件2
      then 命令2
    else
    命令3 fi 结束if

     用例1:vi createHomeData.sh

    #!/bin/bash
    #在用户home目录下,如果不存在data目录就创建data目录,然后拷贝数据到该目录
    dir=${HOME}"/data"  #字符串连接,将$HOME变量和字符串"/data"连接
    if [ ! -e $dir ]
      then
        echo "目录$dir不存在,创建..."
        mkdir -p $dir
        cp /opt/elasticsearch*/config/*.yml $dir
    else
        cp /opt/elasticsearch*/config/*.yml $dir
    fi
    ls -d $dir
    ls -l $dir

    用例2:vi checkHost.sh

    #!/bin/bash
    #检查参数1所表示的主机是否在线
    if [ -z $1 ]
      then
       echo "请输入主机IP或名字"
       exit
    fi
    echo "正在连接..."
    ping -c 3 -i 0.2 -W 3 $1 &> /dev/null
    if [ $? -eq 0 ]
      then
        echo "Host:$1在线"
    else
        echo "Host:$1不在线"
    fi
    [es@bigdata-senior01 ~]$ ./checkHost.sh www.google.com
    正在连接...
    Host:www.google.com不在线
    [es@bigdata-senior01 ~]$ ./checkHost.sh 114.114.114.114
    正在连接...
    Host:114.114.114.114在线
    [es@bigdata-senior01 ~]$ ./checkHost.sh
    请输入主机IP或名字

    检查端口是否开放

    #!/bin/bash
    if [ -z $1 ] ; then 
      echo "请输入需要检测IP和端口文件" 
      exit
    fi
    
    if [ ! -e $1 ] ; then
      echo "文件不存在,请重新确认"
      exit
    fi
    
    File=$1
    
    cat $File | while read host
    do
    nc -zvw5 $host &> /dev/null
    if [ $? -eq 0 ] ; then echo "host: $host 开放"
    else echo "host: $host 关闭"
    fi
    
    done
    

    用例3: vi checkScores.sh

    #!/bin/bash
    #输入分数,判断分数等级
    read -p "输入分数0-100: " grade
    if [ $grade -ge 90 ] && [ $grade -le 100 ] ; then
      echo "grade A"
    elif [ $grade -ge 75 ] && [ $grade -lt 90 ] ; then
      echo "grade B"
    elif [ $grade -ge 60 ] && [ $grade -lt 75 ] ; then
      echo "grade C"
    else
      echo "grade D"
    fi

    8.2 for循环

    语法:
    for 被循环自动赋值的变量 in 取值列表
    do
      执行各种命令
    done 

    用例1:vi createUsers.sh

    先准备一个userlist.txt,里面加一下用户名称,如下:
    [es@bigdata-senior01 ~]$ cat userlist.txt
    tom
    amy
    xu.dm
    xu.dm.test
    bus
    dba

    编辑createUsers.sh脚本

    #!/bin/bash
    # 用重定向到/dev/nul来屏蔽屏幕输出
    # 脚本后面需要一个文件名参数
    if [ -z $1 ] ; then
      echo "请在脚本后面输入用户文件列表"
      exit
    else
      if [ ! -e $1 ] ; then
        echo "输入的文件不存在,请检查后重新输入"
        exit
      fi
    fi
    
    read -p "请输入用户密码:" password
    users=$(cat $1) #注意等号两边不能有空格,shell语法坑死人
    echo $users
    for uname in $users
    do
    id $uname &> /dev/null
    if [ $? -eq 0 ] ; then
      echo "$uname,用户已经存在!"
    else
      useradd $uname &> /dev/null
      echo "$password" | passwd --stdin $uname &> /dev/null
      if [ $? -eq 0 ] ; then
        echo "$uname,创建成功"
      else
        echo "$uname,创建失败"
      fi
    fi
    
    done
    执行脚本:
    [es@bigdata-senior01 ~]$ sudo ./createUsers.sh userlist.txt 
    请输入用户密码:123@abc.com
    tom amy xu.dm xu.dm.test bus dba
    tom,创建成功
    amy,创建成功
    xu.dm,用户已经存在!
    xu.dm.test,创建成功
    bus,创建成功
    dba,创建成功

    用例2:vi checkHosts.sh,检查文件列表里的主机是否在线

    #!/bin/bash
    if [ -z $1 ] ; then
      echo "请输入主机列表文件"
      exit
    fi
    
    if [ ! -e $1 ] ; then
      echo "文件不存在,请检查后重新输入"
      exit
    fi
    
    hostlist=$(cat $1)
    for host in $hostlist ; do
    ping -c 3 -i 0.2 -W 3 $host &> /dev/null
    if [ $? -eq 0 ] ; then
      echo "host:$host 在线"
    else
      echo "host:$host 不在线或被屏蔽"
    fi
    
    done
    [es@bigdata-senior01 ~]$ ./checkHosts.sh hosts.txt
    host:192.168.1.2 在线
    host:www.baidu.com 在线
    host:www.google.com 不在线或被屏蔽
    host:www.cnblogs.cn 在线
    host:www.csdn.net 在线
    host:www.qq.com 在线

    8.3 while语句

    语法:
    while 条件测试语句
    do
        执行命令
    done

    用例1:vi outputNum.sh

    #!/bin/bash
    #倒序输出数字
    if [ -z $1 ] ; then
      echo "please input a integer number[1-100]"
      exit
    fi
    
    if [ $1 -gt 100 ] || [ $1 -lt 1 ] ; then
      echo "error num,need number between [1-100]"
      exit
    fi
    num=$1
    while [ $num -ge 1 ] ; do
      echo "num:$num"
      #num-1有三种写法
      #let "num=$num - 1"  
      #num=$(expr $num - 1)
      let num--
    done

    用例2:

    #!/bin/bash
    #测试随机数,需要输入测试次数
    if [ -z $1 ] ; then
      echo "please input test count number"
      exit
    fi
    
    count=$1
    num=1
    while [ $count -gt 0 ]
    do
      echo "第$num次,随机数:$RANDOM"
      let num++
      let count--
    done

    8.4、case语句

    case 变量值 in
    模式1)
       命令1;;
    模式2)
       命令2;;
    *)
      其他命令;;
    esac #就是case反过来和if语句类似,我已经不想吐槽这是什么逻辑
    模式字符串中可以使用通配符
    如果一个模式字符串中包含多个模式,那么各模式之间应以竖线(|)隔开,表各模式是“或”的关系,即只要给定字符串与其中一个模式相配,就会执行其后的命令列表。
    各模式字符串应是唯一的,不应重复出现,并且要合理安排它们的出现顺序。

    用例1:修改上面的testRandom.sh

    #!/bin/bash
    #测试随机数,需要输入测试次数
    if [ -z $1 ] ; then
      echo "please input test count number"
      exit
    fi
    
    case $1 in
    *[a-z]* | *[A-Z]*)
      echo "输入的是字母,需要输入数字"
      exit;;
    *[0-9]*)
      echo "输入的是数字,符合要求";;
    *)
      echo "输入非法字符无法继续"
      exit;;
    esac
    
    count=$1
    num=1
    while [ $count -gt 0 ]
    do
      echo "第$num次,随机数:$RANDOM"
      let num++
      let count--
    done

    9、break和continue

    break:用于立即终止当前循环的执行,break命令可以使用户从循环体中退出来。
    语法:break[n] ,其中,n表示要跳出几层循环,默认值为1
    
    continue:跳过循环体中在其之后的语句,会返回到本循环层的开头,进行下一次循环。
    –语法:continue[n],其中,n表示从包含continue语句的最内层循环体向外跳到第几层循环,默认值为1,循环层数是由内向外编号。



     
  • 相关阅读:
    【转】cocos2d-x使用第三方的TTF字体库
    CCControlSlider和CCControlStepper用法
    Cocos2d-x中获取设备语言的方法
    ccrendertexture
    【转】如何使用KeyChain保存和获取UDID
    【luogu P4777】【模板】扩展中国剩余定理(EXCRT)(数论)
    【luogu P1495】【模板】中国剩余定理(CRT)/曹冲养猪(数论)
    【luogu P3980】Volunteer / 志愿者招募(网络流)
    凡喵识图 / Image Recognition(鸽笼原理)(模拟)
    回文树(并查集)(倍增)(LCA)(ST 表)
  • 原文地址:https://www.cnblogs.com/asker009/p/10239645.html
Copyright © 2011-2022 走看看