脚本进阶笔记整理

一、逻辑运算

变量:

  本地变量、环境变量、局部变量、位置参数变量、特殊变量

  变量赋值:name=value,export name=value,declare -x name=value

  变量引用:$name,${name}

  注意:有些时候{}不能省略,例如

       echo “$valuemagedu.com” 

       echo “${value}magedu.com”

   撤销:unset name

bash脚本编程,运行脚本

#!/bin/bash      #称为shebang是bash脚本的默认开头行固定格式

#             #   #号后面是注释信息,不显示也不影响脚本执行结果

空白行          忽略不显示行

bash的配置文件

porfile类:登录式shell

bashrc类:非登录式shell

登录式shell:/etc/profile–>/etc/profile.d/*.sh–>~/.bash_profile–>~/.bashrc–>/etc/bashrc

非登录式shell:~/.bashrc–>/etc/bashrc–>/etc/profile.d/*.sh

    

算数运算

   +,-,*,/,**(乘次方),%(求模取余)

在bash中默认数据类型都是字符串形式,做算数运行需要经特殊方法才可以

示例:     

[root@localhost ~]# num1=2
[root@localhost ~]# num2=9
[root@localhost ~]# echo "${num1}+${num2}"
2+9
[root@localhost ~]# declare -i num3=5
[root@localhost ~]# declare -i num4=9
[root@localhost ~]# echo "${num3}+${num4}"
5+9

算术运算格式:

(1)let VAR=算数运算表达式

[root@localhost ~]# let ${num1}+${num2}

#默认不输出结果到屏幕,所以需要赋值给变量,再引用

[root@localhost ~]# let sum5=${num1}+${num2}
[root@localhost ~]# echo ${sum5}
11

let 参数 [参数 …]

   算术运算格式含义

    num++,num– (两个减号不是大横线)变量后递增,后递减

     ++num,–num(两个减号不是大横线)变量前递增,前递减

     +,-加法、 减法

     !,~ 逻辑和按位求反

     ** 求幂运算(乘次方)

     *,/,%  乘法,除法,求模(求余)           

     <<,>> 左和右移位

     <=,>=,<,> 比较

      ==、 != 平等,不平等

      & 按位与

     ^ 按位异或

     | 按位或

      && 逻辑与

      || 逻辑或

      expr ?expr: expr

条件运算符

       =, *=, /=, %=,+=, -=, <<=, >>=,&=,^=,|= 赋值

变量也可以作为let 命令的参数              

(2)VAR=$[算数运算表达式]   

但是不能直接运行,赋不赋值给变量都可以,需要命令直接引用,如echo

[root@localhost ~]# $[${num2}+${num3}]
bash: 14: 未找到命令...
[root@localhost ~]# echo "$[${num2}+${num3}]"
14

(3)VAR=$((算数运算表达式))  

但是不能直接运行,赋不赋值给变量都可以,需要命令直接引用,如echo

[root@localhost ~]# $((${num2}+${num3}))
bash: 14: 未找到命令...
[root@localhost ~]# echo $((${num2}+${num3}))
14

(4)expr EXPRESSION 或 VAR=$(expr EXPRESSION)

  expr OPTION

示例:

[root@localhost ~]# num1=2
[root@localhost ~]# num2=4
[root@localhost ~]# expr ${num1} + ${num2}
6
[root@localhost ~]# sum=$(expr ${num1} \* ${num2})
#注意乘法*符号需要转意(原因是*号在有些场景中为glob通配符)
[root@localhost ~]# echo "${sum}"
8

expr 参数的算术运算格式

                ARG1 | ARG2

                ARG1 是否为 null,也不是 0,否则为 ARG2

                ARG1 & ARG2

                ARG1 如果参数都不是 null 或 0,否则为 0

                ARG1 < ARG2

                ARG1 小于 ARG2

                ARG1 <= ARG2

                ARG1 小于或等于 ARG2

                ARG1 = ARG2

                ARG1 等于 ARG2

                ARG1 != ARG2

                ARG1 ARG2 不等于

                ARG1 >= ARG2

                ARG1 是大于或等于 ARG2

                ARG1 > ARG2

                ARG1 大于 ARG2

                ARG1 + ARG2

                ARG1 和 ARG2 的算术总和

                ARG1 -ARG2

                ARG1 减 ARG2 的算术差

                ARG1 * ARG2

                ARG1 和 ARG2 的算术积

                ARG1 / ARG2

                ARG1 除以 ARG2 的算术商

                ARG1 % ARG2

                ARG1 除以 ARG2 的算术余数

注意:算数运算格式内各参数彼此之间必须有空格,并且shell脚本不支持浮点型

增强型赋值:

       变量做某种算数运算后回存至此变量中;

            eg:  

               let i=$i+#

               let i+=#

            还有:+=,-=,*=,/=,%=

            自增:

                 VAR=$[$VAR+1]

                 let VAR+=1  

                 let VAR++

            自减:

                 VAR=$[$VAR-1]

                 let VAR-=1

                 let VAR–

         

二、条件测试:

     判断某需求是否满足,需要由测试机制来实现;

     如何编写测试表达式以实现所需的测试;

       (1)执行命令,并利用命令状态返回值来判断

          0:成功

          1-255:失败

       (2)测试表达式

           test EXPRESSION   eg:test 3 -gt 2

            [ EXPRESSION ]

            [[ EXPRESSION ]]

        注意:EXPRESSION两端必须有空白字符,否则有语法错误

bash的测试类型:

          数值测试:数值比较

                 -eq:是否等于;     eg:[ $num1 -eq $sum2 ]

                 -ne:是否不等于

                 -gt:是否大于

                 -ge:是否大于等于

                 -lt:是否小于

                 -le:是否小于等于

          字符串测试:

              ==:是否等于;(字符串)

一个=号也可以由于赋值变量用=号,但是赋值并不应用到[]中,所以能够使用,但是还是推荐使用双=号

              >:是否大于

              <:是否小于

             !=:是否不等于

             =~:左侧字符串时候能够被右侧的PATTERN所匹配;(模糊匹配而非精确匹配) 

示例:

[root@localhost ~]# [[ tom =~ tom ]]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [[ tom =~ om ]]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [[ tom =~ o ]]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [[ tom =~ x ]]
[root@localhost ~]# echo $?
1

-z “STRING”:判断指定的字符串是否为空,空为真,不空为假

-n “STRING”:判断指定的字符串是否为不空,不空为真,空为假  

注意:(1)字符串测试时:字符串要加引号,表示引用有变量命令””,没有变量命令使用”

    (2)作比较时,尽量使用[[]];

   (3) 但是在组合测试时,[[]]有时会有语法错误,所以可以使用[]

示例:

[root@localhost ~]# [ var1 == var1 ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ var1 == Var1 ]
[root@localhost ~]# echo $?
1
[root@localhost ~]# [ var1 == ${Var2} ]
-bash: [: var1: 期待一元表达式
[root@localhost ~]# [ var1 == "${Var2}" ]
[root@localhost ~]# echo $?
1
[root@localhost ~]# [ a > b]
-bash: [: 缺少 `]'
[root@localhost ~]# [ a > b ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ a < b ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ "a" < "b" ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ "a" > "b" ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [[ "a" > "b" ]]
[root@localhost ~]# echo $?
1

文件测试:

     存在性测试:

            -a FILE  少使用

            -e FILE 推荐使用

文件存在则为真,否则为假  

存在性及类型测试:

            -b FILE:是否存在并且为块设备文件;

            -c FILE:是否存在并且为字符设备文件;

            -d FILE:是否存在并且为目录文件;

            -f FILE:是否存在并且为普通文件;

            -h FILE 或 -L FILE:是否存在并且为符号链接文件;

            -p FILE:是否存在并且为管道文件;

            -S FILE:是否存在并且为套接字文件;

文件权限测试:

            -r FILE:是否存在并且对当前用户可读;

            -w FILE:是否存在并且对当前用户可写;

            -x FILE:是否存在并且对当前用户可执行;

特殊权限测试:

           -u FILE:是否存在并且拥有suid权限;

           -g FILE:是否存在并且拥有sgid权限;

           -k FILE:是否存在并且拥有sticky权限;

注意:对于脚本则是当前运行此脚本的用户

文件是否有内容:

          -s FILE:是否有内容;

时间戳测试:

       -N FILE:文件自从上一次读取操作后是否被修改过

从属关系测试:

       -O FILE:当前用户是否为文件的属主;

       -G FILE:当前用户是否属于文件的属组;

双目测试:

     FILE 1 -ef FILE2 :FILE1与FILE2是否指向同一个文件系统的相同inode的硬链接;

     FILE 1 -nt FILE2 :FILE1的最近一次更新时间是否新于FILE2的最近一次更新时间

     FILE 1 -ot FILE2 :FILE1的最近一次更新时间是否旧于FILE2的最近一次更新时间

组合测试条件:

       逻辑运算:

       第一种方式:

             COMMAND1 && COMMAND2

             COMMAND1 || COMMAND2

             ! COMMAND

            eg: [ -O FILE ] && [ -r FILE ]

       第二种方式:

            test EXPRESSION1 -a EXPRESSION2

            [ EXPRESSION1 -a EXPRESSION2 ]

            [[ EXPRESSION1 -a EXPRESSION2 ]]

类此还有

     EXPRESSION1 -o EXPRESSION2

     ! EXPRESSION

eg:[ -O FILE -a -r FILE ]

注意:模式匹配时,势必要激活正则表达式引擎,而使用正则表达式的测试判断,要比单一字符串测试判断要慢,所以尽量避免使用正则表达式进行查找比较和测试;

脚本的状态返回值:

           默认是脚本中执行的最后一条件命令的状态返回值

           自定义状态退出状态码:exit [n]:n为自己指定的状态码;

       注意:shell进程遇到exit时,即会终止,因此,整个脚本执行即为结束;

三、bash脚本语句

过程式编程语言的代码执行顺序:

           顺序执行:从左至右,从上至下,逐一运行

           选择执行:代码有一个分支:条件满足时才会执行

                 两个或以上的分支:只会执行其中一个满足条件的分支

           循环执行:

                 代码片段(循环体)要执行0、1或多次重复运行

选择执行:

     单分支的if语句

    if 测试条件;then 

      代码分支 

      条件为真则执行,为假则不执行

或者

    fi       

    if 测试条件      

     then      

        代码分支                                     

        条件为真则执行,为假则不执行                                        fi                            

双分支的if语句:

         if 测试条件;then

           条件为真时执行的分支

         else

           条件为假时执行的分支

         fi

多分支的if语句:

          if COMDITION1;then

            条件1为真分支

          elif COMDITION2;then

              条件2为真分支

          elif COMDITION3;then

             条件3为真分支

          …

          elif COMDITIONn;then

             条件n为真分支

          else

             所有条件均不满足时的分支

          fi

注意:即便多个条件可能同时都能满足,分支只会执行其中一个,首先测试为“真”;并且if语句可嵌套if等其他语句

case语句的语法格式:

    case $VARAIBLE in

    PATH1)

          分支

          ;;

    PATH2)

          分支

          ;;

    …

    *)

          分支

          ;;

    esac

    注意:双分号如果不加,则会前一个匹配执行后,下一个会接着匹配执行

          适用于一个变量,与多个可能取值比较

          支持glob风格的通配符:

                         *:任意长度的任意字符;

                         ?:任意单个字符

                         []:范围内任意个字符

                         a|b:a或b;

bash脚本编程之用户交互:

    脚本参数

       用户交互:通过键盘输入数据,从而完成变量赋值操作

           read [option]…[name…]

                  -p ‘PROMPT’    提示注释信息

                  -t TIMEOUT     时间限制

       bash -n /path/to/some_script

               检测脚本中的语法错误

       bash -x /path/to/some_script

               调试执行

循环执行:将一段代码重复执行0、1或多次;

     进入条件:条件满足时才进入循环

     退出条件:每一个循环都应该有退出条件,以有机会退出循环

bash脚本:

     for循环

     while循环

     until循环

for循环:

       执行机制:依次将列表中的元素赋值给“变量名” ; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽,循环结束

   两种格式:

     (1)遍历列表

     (2)控制变量

    遍历列表

        for VARAIBLE in LIST;do

             循环体

        done

    进入条件:LIST列表有元素,即可进入循环

    退出条件:列表中的元素遍历完成

    LIST的生成方式:

         (1)直接给出;

         (2)整数列表

                  (a){start…end}

                  (b)seq [start [incremtal]] last

          (3)返回列表的命令:$(COMMAND),例如:ls  cat

         (4)glob通配符

         (5)变量引用;例如$@,$*

    格式示例:

    #!/bin/bash

    #

    for username in user1 user2 user3;do

        if id $username &>/dev/null;then

           echo “$username exists.”

        else

           useradd $username && echo “Add user $username finished.”

        fi

    done

    示例:求100以内的正整数之和

    #!/bin/bash

    #

    delcare -i sum=0

    for i in {1..100};do

        echo “\$sum is $sum,\$i is $i”

        sum=$[$sum+$i]

    done

    echo $sum

    示例:判断/var/logm目录下的每一个文件的内容类型

    #!/bin/bash

    #

    for filename in /var/log/*;do

    if [ -f $filename ];then

       echo “Common file.”

    elif [ -L $filename ];then

       echo “Sysbolic link”

    elif [ -d $filename ];then

       echo “Directory.”

    elif [ -b $filename ];then

       echo “block special file.”

    elif [ -c $filename ];then

       echo “character special file.”

    elif [ -S $filename ];then

       echo “Socket file.”

    else

       echo “Unkown.”

    fi

    done

while循环:

     while CONDITION;do

           循环体

           循环控制变量修正表达式

     done

     

     CONDITION:循环控制条件;进入循环之前,先做一次判断;每一次循环之后会再次做判断;条件为“true”,则执行一次循环;直到条件测试状态为“false”终止循环,因此:CONDTION一般应该有循环控制变量;而此变量的值会在循环体不断地被修正

     进入条件:CONDITION测试为“真”

     退出条件:CONDITION测试为“假”

     示例:求100以内的正整数之和

     #!/bin/bash

     #

     declare -i sum=0

     declare -i i=1

     while [ $i -le 100 ];do

          sum=$[$sum+$i]

          let i++

     done

     echo $sum

原创文章,作者:cnc,如若转载,请注明出处:http://www.178linux.com/71736

(0)
cnccnc
上一篇 2017-03-26
下一篇 2017-03-26

相关推荐

  • 【N25第七周作业】

    1、创建一个10G分区,并格式为ext4文件系统;    (1) 要求其block大小为2048, 预留空间百分比为2, 卷标为MYDATA, 默认挂载属性包含acl; [root@localhost ~]# mke2fs -t ext4 -b 2048 -m 2 -L MYDATA /dev/sdb1 mke2fs 1.42.9 (28…

    2017-04-13
  • centos6.9实现网卡bonding

    centos6.9实现网卡bonding 为什么要用bonding  将多块网卡配置同一IP地址实际中是不可能的。通过bonding,虚拟一块网卡对外提供连接,物理网卡被修改为相同的MAC地址,这样可以实现多块网卡绑定同一IP地址,对外提供服务。用于网络负载均衡和网络冗余。 工作模式  bonding的模式:0-6,即:7种模式,这里我们…

    2017-08-20
  • vim编辑器

                                                      &nbsp…

    Linux干货 2015-12-19
  • N26-博客作业-week6

    vim:Vi IMprove 基本模式:编辑模式,命令模式输入模式末行模式 打开文件: vim [option] [file…] +#:打开文件后,直接让光标处于第#行的行首+/PATTERN:打开文件后,直接让光标处于第一个被PATTERN匹配到的行的行首 模式转换:编辑模式:默认模式编辑模式 –> 输入模式:i:insert…

    Linux干货 2017-03-12
  • 马哥教育21期网络班—第15周课程+练习—-awk 总结

    GNU awk: 文本处理三工具:grep, sed, awkgrep, egrep, fgrep:文本过滤工具;pattern sed: 行编辑器 模式空间、保持空间 awk:报告生成器,格式化文本输出; AWK: Aho, Weinberger, Kernighan&nbsp…

    Linux干货 2016-11-14
  • 在linux中创建虚拟网卡(网卡别名)的方法

    由于业务需要,要在单个物理网卡上建立多个虚拟网卡,操作如下:cd /etc/sysconfig/network-scripts/   #进入网卡目录cp ifcfg-eth0 ifcfg-eth0:1   # 复制出ifcfg-eth0:1虚拟网卡vim ifcfg-eth0:1    #配置ifcfg-eth0:1虚…

    Linux干货 2016-09-06