脚本进阶笔记整理

一、逻辑运算

变量:

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

  变量赋值: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

相关推荐

  • 如何修复Ubuntu 12.04上时间不正确的问题

    大家好: 今天跟大家分享下如何修复ubuntu 12.04上时间不正常的问题。 1–首先打date查看系统的时间是否正常 martell@cnux10:~/sistes/sha-mmb-o2o2o$ date  Thu Dec  1 09:15:47 UTC 2016 martell@cnux10:~/sistes/sha-m…

    Linux干货 2016-12-04
  • N28-第三周博客作业

    1、列出当前系统上所有已经登录的用户的用户名,注意:同一个用户登录多次,则只显示一次即可。
    2、取出最后登录到当前系统的用户的相关信息。
    3、取出当前系统上被用户当作其默认shell的最多的那个shell。
    4、将/etc/passwd中的第三个字段数值最大的后10个用户的信息全部改为大写后保存至/tmp/maxusers.txt文件中。
    5、取出当前主机的IP地址,提示:对ifconfig命令的结果进行切分。
    6、列出/etc目录下所有以.conf结尾的文件的文件名,并将其名字转换为大写后保存至/tmp/etc.conf文件中。
    7、显示/var目录下一级子目录或文件的总个数。
    8、取出/etc/group文件中第三个字段数值最小的10个组的名字。
    9、将/etc/fstab和/etc/issue文件的内容合并为同一个内容后保存至/tmp/etc.test文件中。
    10、请总结描述用户和组管理类命令的使用方法并完成以下练习:
    (1)、创建组distro,其GID为2016;
    (2)、创建用户mandriva, 其ID号为1005;基本组为distro;
    (3)、创建用户mageia,其ID号为1100,家目录为/home/linux;
    (4)、给用户mageia添加密码,密码为mageedu;
    (5)、删除mandriva,但保留其家目录;
    (6)、创建用户slackware,其ID号为2002,基本组为distro,附加组peguin;
    (7)、修改slackware的默认shell为/bin/tcsh;
    (8)、为用户slackware新增附加组admins;

    Linux干货 2017-12-19
  • Linux进程查看与管理命令总结

    Linux进程查看与管理命令总结 内核的功能: 进程管理 文件系统 网络功能 内存管理 驱动程序 安全功能 Process:运行中程序的一个副本。(存在生命周期) Linux内核存储进程信息的固定格式:task struct 多个任务的task struct组件的链表:task list 进程创建: init 父子关系 进程:都有其父进程创建 fork(),…

    Linux干货 2016-09-07
  • 脚本之循环的特殊用法及函数的使用

    一、本文主要时针对while for select循环结果的特殊用法进行讲解。     1、while循环的特殊用法                 while read…

    Linux干货 2016-08-21
  • linux中数组的定义与使用

            我们常说,程序=指令+数据,往细一点的方向说,指令具体指的有哪些?数据又有哪些? 总结一下: 指令大概包括,编程语言中的语法关键字(如bash编程中的关键字有for,while,case,if,until,continue,break),还包括系统中的命令,和一些自己编写的函数,这些…

    2017-05-23
  • Linux Bash脚本编程练习

    马哥教育网络班23期+第九周课堂练习 Linux Bash脚本编程练习 练习 1.写一个脚本,判断当前系统上所有用户的shell是否为可登录shell (即用户的shell不是/sbin/nologin) 分别统计这2类用户的个数,通过字符串比较来实现 脚本: 测试结果:  。。。 2.写一个脚本 (1)获取当前主机的主机名 保存于hostname…

    Linux干货 2016-11-28