bash脚本编程

作者: 若与 | 来源:发表于2018-06-26 23:44 被阅读2次

    编程语言:

    编译器,解释器
    编程语言:机器语言,汇编语言、高级语言
    静态语言:编译型语言
    强类型(变量)
    关键字:
    事先转换成可执行格式
    c,c++,JAVA,C#
    动态语言:解释型语言 on the fly
    弱类型
    边解释变执行
    php,shell,python,perl(面向过程)


    面向对象:shell,c
    面向对象:JAVA,Python,perl,C++


    bash:脚本解释器

    编程能力:
    脚本编程

    变量:内存空间,命名的内存空间(可以回收)
    内存:编址的存储单元

    进程:临时存储数据要用到变量

    映射表:变量名和物理地址的映射

    变量类型:
    事先确定数据的存储格式和长度
    字符
    数值
    整型
    浮点型:11.23(1.12310^1)(0.112310^2)
    2013/10/10
    布尔型:真假型 逻辑

    逻辑运算:与、或,非、异或(相同为假,不同为真)
    &, !
    短路逻辑运算
    与:其中一个为假,结果为假
    或:其中一个为真,结果为真。

    shell:弱类型编程语言

    强:变量在使用前,必须事先声明,甚至还需要初始化:
    弱类型编程语言:变量用时声明,甚至不区分类型:(默认为字符)

    显式转换,隐式转换
    1+c=(ASCII)

    10:16bit
    10:1010,8bit

    整型:8bit,256
    0-255;溢出
    缓冲区溢出:攻击(填入数据前,先判断)

    变量赋值:var_name=value

    bash变量类型:
    环境变量
    本地变量(局部变量)
    位置变量
    特殊变量

    本地变量:(作用域当前bash)
    变量声明: varname=value

    局部变量(作用域为当前代码)
    local varname=value

     bash:进程的变量
     echo $VAR_name
    

    引用变量:${VARNMAE} $varname(防止混淆要用{})
    ''强引用
    “” 弱引用
    环境变量(作用域为当前shell进程及其子进程)

    export varname=value
      “导出”
      varname=value
      export varname
    

    脚本在执行时会启动一个子shell进程,
    命令行中启动的脚本就会继承当前shell环境变量
    系统自动执行的脚本(非命令行启动)就需要自我定义需要各环境变量。

    位置变量:
    $1,$2,$3,......

    特殊变量:
    $?:上一个命令的执行状态返回值(回传码)
    程序执行结果
    程序状态返回代码(0-255)
    0:表示正确
    1-255:表示错误 1,2,127系统预留
    id 用户
    echo $?

    输出重定向:

    <
    2>
    2>>
    &>

    /dev/null:设备,软件设备(软件模拟) ,bit bucket,数据黑洞

    id student &> /dev/null
    echo $?
    

    撤销变量:

    set (省略)
    unset  varname
    

    查看当前shell的变量:(本地变量,环境变量)

      set   (所有变量)
    查看当前shell中的环境变量
    printenv
    env
    export
    

    变量添加

    animal=$animal:goat
    animal=$animal:shell
    export PATH=$PATH:/usr/local/apache/bin
    export PATH=/usr/local/apache/bin/:$PATH
    

    默认为字符串

    脚本:命令的堆砌,按实际需求,结合命令流程控制机制实现的源程序。

    ELF:可执行的链接的二进制文件。

    shebang:魔数
    #!/bin/bash(可执行程序的路径)
    #:注释行,不执行
    chmod +x *.sh
    ./*.sh(独立执行)
    
    
    bash *.sh   (可以没有执行权限)
    

    练习:写一个脚本:

    1.添加5个用户,user1,user5
    2.每个用户的密码同用户名,而且,添加密码完成后不显示passwd命令的执行结果
    3.每个用户添加完成后,都要显示用户某某已完成。
    练习:写一个脚本:
    1.使用一个变量保存一个用户名
    2.删除此变量中的用户,且一并删除其家目录
    3.显示“用户删除完成”类的信息。

    条件判断:
    如果用户不存在
    添加用户,给密码并显示添加成功。
    否则
    显示已经存在,不添加。
    bash中如何实现条件判断:
    条件测试类型:
    整数测试
    字符测试
    文件测试

    条件测试的表达式:
    [ expression ] (注意空格)
    [[ expression ]]
    test expression

    整数比较:

      -eq:测试两个整数是否相等:比如   [ $A -eq  $B ]  echo $?
      -ne:测试两个整数是否不等,不等为真,相等为假 
      -gt:测试一个数是否大于一个数:大于为真,小于为假
      -lt:测试一个数是否小于 一个数。
      -ge:测试一个数是否大于等于一个数
      -le:小于等于
    

    命令间逻辑关系:
    逻辑与: &&
    第一个条件为假时,第二个条件不用再判断了,最终结果已经有了
    第一个条件为真时,第二个条件必须判断。
    逻辑或:|| 第一个条件为假时,第二个条件判断
    第二个条件为真时,第二个条件不判断
    (短路操作)
    id user01 && echo "hello,user1"
    id user1 || useradd user1

    变量名称:
    1.只能包含字母、数字、下划线、并且不能数字开头
    2.变量名不能和系统变量同名
    3.最好做到见名知义。

        ! id user2 && useradd user2
    [ $FINELINE -gt 100 ] && echo "/etc/inittab is a big file " || echo "/etc/inittab is a small file"
    
    id user1 && echo "user is exists" || useradd user
    ! id user && useradd user && echo "user exits"
    ! id userr &&  useradd user && echo "nihao"  | passwd --stdin user  || echo "user is exits" 
    如果用户存在,就显示用户已存在;否则,就添加此用户;
    id user1 && echo "user1 exists." || useradd user1
    
    如果用户不存在,就添加;否则,显示其已经存在;
    ! id user1 && useradd user1 || echo "user1 exists."
    
    如果用户不存在,添加并且给密码;否则,显示其已经存在;
    ! id user1 && useradd user1 && echo "user1" | passwd --stdin user1  || echo "user1 exists."
    
    条件判断:控制结构:
    单分支if语句:
    if 判断条件 ; then (如果then 和 if 不在一行  可以省略;)
         statement1
         statement2
         ....
    fi 
    
    双分支的if语句:
    if 判断条件 ; then
        statement1
        statement2
        ....
        else
        statememt3
        ...
    fi 
    
            userid=`id -u $username` 
        if [ $userid -eq 0] ;then
             echo "it is admin"
             else
               echo  "it is not admin"
        fi
    
    if id $name ;then
        判断用户是否存在
        
        
    #!/bin/bash
    username=user1
    userid=`id -u $useranme`
    groupid=`id -g $useranm`
    if [ $userid -eq $groupid ] ;then
      echo "good guy"
      else
           echo "bad guy"
    fi
    

    shell中进行算术运算:

    a=1
    b=2 
    let: 让字符转换成数值进行算术运算
    1.let 算术运算表达式
       let c=$a+$b 
    2.$[算术运算表达式]
      c=[$a+$b]
    3.$((算术运算表达式))
       c=(($a+$b)
    4.expr 算术运算表达式   (注意表达式中各操作数及运算符之间要有空格) 
    c=`expr $a + $b`
    

    提前结束脚本

      exit:退出脚本。可以自定义回传码(命令执行状态码),没有跟数字,默认最后一次执行的状态码。
       exit 数值#
    

    测试方法:

    [  expression ]命令 
    [[ expression ]] 关键字 
    test expresión
    

    bash常见的测试有三种:
    整数测试:

    -gt
    -le;
    -ne
    -eq
    -lt
    -ge:
    
    [ $a -eq 4b ]
    [[ $a -eq $b ]]
    test $a -eq $b
    
     
    文件测试:
    -e file   :测试文件是否存在
    -f  file   测试文件是否为普通文件
    -d file    测试文件是否为目录
    -r  file   测试当前用户对指定文件是否有读取的权限
    -w   file  
    -x   file 
     [  -e /etc/inittab ]
     [ -w /etc/rc.d/rc/sysconfig ]   
     
    if [ ! -e $FILE ];then 
     echo ""
      exit 0
    
    圆整:丢弃小数点后的数。
    

    多分支的if语句

    if 判断条件1; then
      statement1
      .......
      elif  判断条件2;then
          statement2
          ......
          elif   判断条件3;then
               statement3
               ...
            else
               statement4
               ....
    fi
    

    测试脚本是否有语法错误:

    bash -n file.sh
    bash -x 脚本  单步执行命令
    

    编写一个脚本

    给定一个文件,如果是普通文件,就显示
    如果是目录,就显示目录,否则此为不能识别。
    
    #!/bin/bash
    
    FILE=/etc/rc.d/rc.sysconfig
    if [ ! -e $FILE ];then
        echo "NO such file"
    fi
    if  [ -f $FILE ];then
       echo "common file"
       elif [ -d $FILE ];then
          echo "$FILE is directory "
          else
            echo "UNknown"
    fi
    
    定义退出状态码
    exit:退出脚本
    exit #
    如果脚本没有明确定义退出状态码,那么执行最后一条命令的的状态码即为脚本的退出状态码。
    

    bash变量的类型:

    本地变量(局部变量):作用域只是当前shell
    环境变量:作用域是当前shell,及其子shell
    位置变量:$1,$2,$3....

    shift:轮替 位置参数的轮替。
     #!/bin/bash
     echo $1
     shift
     echo $
     shift
     echo $1 
     shift
     
     shift #:一下轮替n个
     
    
     
    ./filetest.sh  /etc/fstab /etc/inittab
    $1: /etc/fstab
    $2: /etc/inittab
    
    

    特殊变量:

    $?:
    $#:参数的个数
    $*:参数列表
    $@:参数列表
    
    

    练习:写一个脚本

    能接受一个参数(文件路径)
    判定:此参数

    #!/bin/bash
    
    if [ $# -eq 0 ];then
    echo""
     exit 0
    if [ ! -e $1  ];then
        echo "NO such file"
    fi
    if  [ -f $1  ];then
       echo "common file"
       elif [ -d $1  ];then
          echo "$1  is directory "
          else
            echo "UNknown"
    fi   
    

    特殊变量:

    $?:
    $#:参数的个数
    $*:参数列表
    $@:参数列表
    

    字符串测试:

    ==或=:   [ $a == $b ]  (等号两端要有空格)
    !=:测试是否不等,不等为真,相等为假。
    >
    <
    =>
    <=
    
    -n string :测试指定字符串是否为空,空为真,不空为假。
    -s  string :测试指定字符串是否为空,空为假,不空为真。
    
    #!/bin/bash
    if ! id $1 &> /dev/null;then
          echo "no user"
            exit 1
    fi
    if [ `id -n -u $1` == `id -n -g $1` ];then
       echo      "yiyang"
       else
             "buyiyang"
    fi
    
    if  [ $1 == "q" ];then
        echo "quiting..."
       exit 1
       elif [ $1 == 'Q' ];then
         echo "quiting.."
         exit 2
         esle 
         exit 3
    fi
    
    echo "scale=2;111/22;" | bc
    bc <<<  "scale=2;111/22;"(注意3个小于号)
    
    

    循环:进入条件,退出条件

    for
    while
    until
    
    for   变量 in 列表;do
           循环体
         done
    
    for i in 1 2 3 4 5 6 7 8 9 10;do
        加法运算
        done
        
        遍历完成后,退出。
    
    
    如何生成列表:
    {1..100}
    seq  起始数 步进长度  结束数
    
    
    #!/bin/bash
    
    let sum=0
    for i in {1..100};do
       let sum=$sum+$i
    done 
    echo "$sum"
    

    decalre -i sum

    declare  
      -i:整型 
      -x :声明为环境变量
      
    取模,取余 %
    
    

    测试:

    整数测试:
      -le
      -lt
      -ge
      -gt
      -eq
      -ne
    字符测试:
      ==
     !=
      >
      <
      -n
      -z
    文件测试:
     -f 
      -d
     -r
      -x
     -w
      -e 
    if [ $# -gt 1 ];then
    组合测试条件:
        -a:与关系
        -o:或关系
         !:非关系
    
    if [ $# -gt 1 -a $# -le 3  ]
    if [ $# -gt 1 ] && [ $# -le 3 ]
    
    Q,q,quit 
    if [ $1 == q -o $1 == Q  -o  $1 == quit -o $1 == Quit ];then
            echo "quiting"
           exit 1
    fi
    
    let i=$[$i+1]
    let sum=$[$sum+$i]
    let sum+=$i
    
    let i+=1 
    let i++
    
    -=  i--
    *=
    /=
    %=
    
    ++i,--i  
    

    面向过程:
    控制结构:
    顺序结构
    选择结构
    循环结构
    选择结构:
    if:单分支、双分支的,多分支
    if condaiction;then
    statment
    .....
    fi

    if condation;then
    statment
    ....
    else
    ....
    fi

    if condation;then
    statment
    ..
    elif condation;then
    statment;
    ....
    fi

    case语句:选择结构

    case switch in
    value)
    statment
    ....
    ;;
    value2)
    statment
    ....
    ;;
    *)
    statment
    .....
    ;;
    esac

    由键盘输入一个字符,给出判断?

    case.sh
    #!/bin/bash
    
    case $1 in
    [0-9]) 
       echo "a digtal";;
    [a-z]) 
        echo "lower";;
    [A-Z])
      echo "upper";;
      *)
        echo "unknown";;
    esac
    
    只接受参数,start,stop,restart,status
    
    #!/bin/bash
     case $1 in 
     'stat')
        echo "start server...";;
    'restart')
       echo "restart server...";;
     'stauts')
       echo "stuts service...";;
       *)
         echo "`basename $0` {start |stop |restart |status}";;
         esac
         
    #!/bin/bash
    case $1 in
    -y|--verbose)
      debug=1 
      ;;
      *)
    
    

    脚本编程:
    顺序结构
    选择结构
    if:单分支、双分支的,多分支
    case
    循环结构:
    for
    while
    until

    while循环:适用于循环次数未知的情况下,必须要有退出条件。
    语法: 
         while condition ; do 
              statemant
              ....
              done 
    计算100以内正整数的和:
    #!/bin/bash 
    declare  -i i=1 
    declare -i sum=0 
     while [ $i -le 100  ];do
        let sum+=$1 
          let $i+=1
        done
    
        
      read -p "please input string" string 
    while [  $string != 'quit' ];do
         echo $string |tr 'a-z'  'A-Z'
         read -p "please input string "string 
         done 
        
        
        
    while [ 1 -eq 1 ] 
    or
    while true
    or
    while ((1))
    or
    while [[ 1 ]]
    or 
    while :  
    
    
    while循环 
    while ,until,for 
    break:提前退出循环
    continue:退出本次循环,进行下一次循环。
    
    while的特殊用法一:
    while : ;do
    
    done 
    while的特殊用法二:
    while read LINE;do
    
    done </path/to/somefile
    
    

    函数:功能 function

    代码重用:
    
    库:so
    
    函数:就是把其中某个特定的功能的代码封装起来,进行调用。
    定义函数:
    function FUCname {
        command
    
    }
    FUncname() {
    command
    
    }
    
    function showmenu {
    }
    函数不能直接执行,必须调用才行。
    showmenu
    
    自定义状态返回值
    return #
    
    #!/bin/bash
    ADD() {
    a=9
    b=7
    let c=$a+$b`
    echo $c
    }
    ADD
    sum=`ADD`
    echo $sum
    let m=1
    sm=$[$m+`ADD`]  #函数执行结果引用  ``
    
    ADD 
    echo $?    执行状态结果 
    bash -x *.sh 逐步执行显示
    注意:执行结果,状态结果
    

    函数的执行状态结果是最后一条命令的执行结果的状态返回值。

    自定义状态返回值
    return  #
    0--255
    
    if [ $? -eq 0 ];then
    echo ""
    else 
       fi
    根据返回结果判断程序执行成功与否
    
    接受参数的函数:
    ./a.sh aa bb cc
    位置参数:
    $1:
    $2:
    函数的参数:
    ADD 5 6
    $1 
    $2 :函数参数
    
    ADD(){
      echo $[$1+$2]
    }
    ADD 5 6
    sum=`ADD 5 6`
    echo $sum 
    echo "$i+$j=`ADD $i $j`"
    
    #!/bin/bash
    PING() {
        if ping -c 1 -W 1 $1 &> /dev/null; then
         return 0 
       else
        return 1 
      fi
    }
    for i in {200..254};do
      PING 192.168.0.$i
      if [ $? -eq 0 ];then 
        echo "192.168.0.$i is up"
        else 
        echo "192.168.0.$i is down"
        fi 
      done
    for i in {220..254};do
      PING 172.16.0.$i
    done
    
    if ping 192.168.0.$i ;then
    返回执行状态结果。 
    ``:引用echo结果
      
    
    

    相关文章

      网友评论

        本文标题:bash脚本编程

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