SHELL 编程
    shell 是一个命令解释器,侦听用户指令、启动这些指令、将结果返回给用户(交互式的shell)
    shell 也是一种简单的程序设计语言、利用它可以编写一些系统脚本。

查看本机shell 信息:
    cat /etc/shells        --查看本支持的shell 
    
    echo $SHELL        --查看当前支持的shell 

shell 在执行命令时,各种命令的优先级:
    别名 -> 关键字 -> 函数 -> 内置命令 -> 脚本

    别名:命令的另一种形式,有些情况下可以简化命令的输入,例如可以将很长的命令定义成短别名。
    别名的设置:
    alias  别名= '      '   
    如: alias del='rm -i'
    alias ll='ls -l'

    alias 显示存在的别名
    
   删除别名:unalias del


bash 初始化:
     /etc/profile -> ~/.bash_profile  -> /etc/profile.d/*.sh 
     -> ~/.bashrc  -> /etc/bashrc


bash 退出时也会执行一些脚本
    ~/.bash_logout


bash 命令历史
    默认情况下,shell 执行的命令会保留下来,保存的地方有两个:内存和~/.bash_history
   保存下来后,可以查看,也可以上翻去执行。

   执行的命令先放在内存中,退出窗口时写到 ~/.bash_history

    历史查看:
    history

      cat ~/.bash_history

    历史命令操作:
    !!         执行前一个命令
    !n         执行第n号命令,如 !1023

    !$        表示的是上一次命令的最后一个参数
             如:  mkdir /abc
                          cd !$

    与history 相关的设置 (/etc/profile)
    vim /etc/profile
    
        HISTSIZE=1000    --内存中保存的最大记录条目

        HISTFILESIZE=1000  --历史文件中保留的最大记录条目
        HISTFILE           --指定命令历史文件

禁用命令历史:
    1) HISTSIZE  设置为0
    2) 把历史命令文件链接到/dev/null
    如: ln -s /dev/null ~/.bash_history


shell 中执行命令:
    1、无条件执行多条命令
    ;  隔开
    
    如:mkdir /abc ; cd /abc ;cp /etc/yp.conf /abc

    2、有条件执行多条命令
    &&  前一个命令执行成功后,再执行后一个(前面不成功,后面就不执行了)  
    ||  前一个命令执行不成功时,才执行后一个(前面成功了,后面就不执行了)


    如:[tom@s100 ~]$ mkdir /aaa && cd /aaa && cp /etc/yp.conf /aa
    
    [tom@s100 ~]$ mkdir /aaa || mkdir ~/aaa

   3、子shell中执行
    (   )   把命令括起来

        例:(cd /etc/X11;ls)

   4、命令替换 `  ` 或 $()
      命令替换是将一个命令作为另一个命令的一部分,执行时被替换的部分先执行,执行的给果作为
      参数传给外层命令

      如: mkdir `echo $USER`
             mkdir `date`

          mkdir $(date)

返回值  
    每执行一个命令都有它的返回值,返回值用来标识命令的执行成功与否
    查看上一个命令执行的返回值:echo $?
    0 表示执行成功


shell 中的变量
    shell 中的变量没有严格的类型之分,但不同数据还是有不同的运算符。

    变量定义:
    变量名=值

        注:
            1、变量名由字母、数字、下划线组成,不能以数字开头
            2、变量区分大小写
            3、shell 变量一般以大写命名(习惯,但不是要求)

              如:a=3

    获取变量值的方法:
    $变量名
    或者
    ${变量名}   尽可能用下面这个

         如:
            a=tt
        echo "how are you" > $a_old.txt
         echo "how are you" > ${a}_old.txt 


shell 的变量运算
    1、字符运算
    字符连接
        shell 的字符连接,无须任何符号,只需拼接起来即可
         如:a=3;b=5;c=abcdefg
               echo $a$b$c

    字符处理
        获取长度   ${#变量名}

        例:a="abcdefg"
                   echo ${#a}

        模式匹配  =~
                     
                    如 if [[ $a =~ "^a" ]]

                    判断变量a是否以a开头
    
            取子串   ${变量名:(+/-)n:n}
         
                     +n 从左边第n个位置开始取(第一个字符是0)
                 -n 从右边第n个位置开始取
              
                     n  取多少个

                 s="abcdefg"
             echo ${s:(-3):1}    --从倒数第3个开始,取1个


            字符删除   ${变量名#*截止字符}

              #*x      从左边开始删,遇到第一个x为止
                      ##*x     从左边开始删,遇到最后一个x为止 
        
               %x*     从右边开始删除,遇到第一个x为止
                      %%d*    从右边开始删除,遇到最后一个x为止
                 
        
             str=/dir1/dir2/dir3/dir4/file.txt

             echo {str#*d}    --从左边开始,删到第一个d为止
                          ir1/dir2/dir3/dir4/file.txt

             echo {str##*d}   --从左边开始,删到最后一个d为止
                      ir4/file.txt

                     echo ${str%d*}
                           /dir1/dir2/dir3/

             echo ${str%%d*}
                           /

        basename  取完整路径中的文件名
                      basename /etc/sysconfig/network
                          network
                          
                  basename $str
                       file.txt

    

    2、算术运算
    $[  ]
    $(( ))
     
    如:echo $[3*5]
       echo $((3*8))

    但要注意 shell 算数的能力比较差,小数处理有很多问题
    如在程序需要计算小数,可用 bc 和 awk 
    如:
       echo "scale=2;5/2" | bc
           awk 'BEGIN {print 5/2}'
 

        算术运算符:
        + - * / ** %   

    3、比较运算
    数值比较
        -eq         等于
        -ne        不等于
           -gt        大于
        -lt        小于
            -ge     大于等于
        -le        小于等于

    字符比较
        =        等于
        !=        不等于
        \>        大于
        \<        小于
        -z string    字符是否为空
        -n string     字符是否不为空


    更多的内容可见 man test 


    -b file
    -c file
    -d file
    -e file
    -f file
    -g file    文件是否设置了 sgid
    -G file 
    
    -r file
    -w file
    -x file  

    
    

输入输出:
    输出:  echo 

         格式:echo [option] 字符串
    option:
        -n         不换行
        -e         对一些控制符加以处理
                     如 \t  插入tab
                   \a   发警告音
     
    输入: read 
    格式:read [option] [var]
    option:
       -p          设置提示字符
       -s        输入时不显示,如同输入密码
       -t n     设置等待时间,如果过了指定的秒数,就返回一个非零的状态
           -n n          设置只接收多个字符,达到这个字符个数n后,就自动回车

        如:read -p “请输入你的姓名:" name

       read -sp “请输入密码:" passwd
    
       read -n 1 "是否继续:" jx


cut  
    语法:cut [option] [文件名]
    option:
    -b    取字节
    -c     取字符
    -f     取字段    
    -d    指定字段分隔符
    
    范围表示:
        N          第N项
        N-      从第N项开始,到最后
        N-M     N-M 项
            -M      从1到M
        

    例:只显示 /etc/passwd 中的用户名信息
    cut -d: -f1  /etc/passwd 



shell 程序一般设计流程:
    1、创建一个文件,把完成功能的每一步操作写到脚本文件中
    2、设置文件的可执行权限
    3、执行文件

例:写一程序从键盘读入两个数,输出最大数
    [root@s100 script]# cat if1.sh 
    #!/bin/bash
    #if 使用示例,显示两个数的最大数

    read -p "请输入第一个数:" n1
    read -p "请输入第二个数:" n2
    max=$n1
    if [ $n2 -gt $max ]
    then 
        max=$n2
    fi
    echo "最大数是: $max"


     


        
 

流程控制:
    分支结构
        格式一:
        if [ condition ]    --注意括号两边有空格,condition 是个条件表达式
        then 
        commands
        fi

     作用:判断 ccondition 条件是否成立,如果成立,执行中间的命令 commands
             不成立不执行。

    如: if [ $a -gt $b ]
        then 
        echo "a大于b"
            fi

    
    if 可以接 条件表达式  如 if [ $a -gt $b ],也可以直接接一个命令
    如 if mkdir /abc  ,这时,会把命令的执行结果作为判断,如果成功执行
    就相当于条件成立,如果执行不成功,就相当于条件不成立

    
        格式二:
        if [ condition ]    
        then 
        commands1
        else
        commands2
        fi
 
    作用:判断 condition 条件是否成立,如果成立,执行commands1,如果不成立
         执行 commands2  

    如:if [ $a -gt $b ]
       then 
        echo "a>b"
       else
        echo "b>=a"
       fi

    分支嵌套
        分支嵌套是分支中包含分支
    
    普通的分支形式:
              if [ condition ]
          then 
            commands
          fi
 
    或者
          if [ condition ]
          then 
            commands1
          else
            commands2
          fi

        嵌套后就:
              if [ condition ]
          then 
              if [ condition ]
              then 
            commands1
              else
            commands2
              fi    
          fi

          if [ condition ]
          then 
            if [ condition ]
                    then 
                commands1
            else    
                commands2
            fi
          else
            commands3
          fi


    如:  
        if [ $a -ge 0 ]
            then 
            if [ $a -gt 0 ]
            then 
            b=$a
                else
            b=0
                fi            
        else
        b=$[$a*-1]
        fi


    if [     ]
        then 
        commands1
    else
        commands2
    fi

   例:输入文件,判断是否存在,如果存在,判断当前用户对它的权限
       if [ -f $file ]
       then 
        if [ -r   ...


        if [ -w ....


          if [ -x ...

       else
        echo "文件不存在!"
        exit 1
       fi

   用分支嵌套实现:
       某产品 199 元一件,买5件或以上9折,10件或以上 85 折,输入购买件数,计算付款。

        if [ $n -ge 5 ]
    then 
        

    else
        
    fi

多条件表示:
    逻辑与
    if [ condition1 -a condition2 ]  
    if [ condition1 ] && [ condition2 ]
        if [[ condition1 && condition2 ]]

    逻辑或
    if [ condition1 -o condition2 ]  
    if [ condition1 ] || [ condition2 ]
        if [[ condition1 || condition2 ]]

    逻辑非(取反)
    !