SHELL脚本编程进阶

循环

  1)编程中的逻辑处理:  顺序执行  选择执行  循环执行
  
2)循环执行 

      将某代码段重复运行多次 

      重复运行多少次  

        循环次数事先已知  

        循环次数事先未知 

      有进入条件和退出条件 

   3)for循环

    for 变量名  in 列表;do 

          循环体   

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

      for循环的特殊格式:    

          for ((控制变量初始化;条件判断表达式;控制变量的修正表达式))     do 

                  循环体    

          done 

      控制变量初始化:仅在运行到循环代码段时执行一次 

      控制变量的修正表达式:每轮循环结束会先进行控制变量修正运算,而后再做 条件判断

   4)while循环

      while CONDITION; do  

          循环体   

      done

      CONDITION:循环控制条件;进入循环之前,先做一次判断;每一次循环之后 会再次做判断;

            条件为“true”,则执行一次循环;直到条件测试状态为“false” 终止循环 

            因此:CONDTION一般应该有循环控制变量;而此变量的值会在循环体不断地被 修正 

      进入条件:CONDITION为true 退出条件:CONDITION为false

   5)until循环

      until CONDITION; do 

          循环体 

      done 
        进入条件: CONDITION 为false 退出条件: CONDITION 为true

   6)循环控制语句continue

      用于循环体中 

      continue [N]:提前结束第N层的本轮循环,而直接进入下一轮判断;

             最内层为 第1层     

             while CONDTIITON1; do 

                  CMD1  ... 

                 if CONDITION2; then  

                    continue 

                  fi 

                  CMDn  ...      

             done

  7)循环控制语句break

      用于循环体中 

      break [N]:提前结束第N层循环,最内层为第1层     

              while CONDTIITON1; do 

                    CMD1  ... 

                  if CONDITION2; then  

                    break 

                  fi 

                    CMDn  ...    

              done
   8)select循环和菜单

      select  variable in list      do  

          循环体命令    

      done

      select 循环主要用于创建菜单,按数字顺序排列的菜单项将显示在标准错误上, 并显示 PS3 提示符,等待用户输入 

      用户输入菜单列表中的某个数字,执行相应的命令 

      用户输入被保存在内置变量 REPLY 中 

      select 是个无限循环,因此要记住用 break 命令退出循环,或用 exit 命令终止 脚本。也可以按 ctrl+c 退出循环 

      select 经常和 case 联合使用 与 for 循环类似,可以省略 in list,此时使用位置参量

函数

  9)函数介绍

      函数function是由若干条shell命令组成的语句块,实现代码重用和模块化编程 

      它与shell程序形式上是相似的,不同的是它不是一个单独的进程,不能独立运 行,而是shell程序的一部分                                   函数和shell程序比较相似,区别在于 Shell程序在子Shell中运行 而Shell函数在当前Shell中运行。                                     因此在当前Shell中,函数可以对shell中变 量进行修改

  10)定义函数

      函数由两部分组成:函数名和函数体 

      help function 

        语法一:  f_name (){

                   ...函数体... 

             } 

        语法二:  function f_name {

                    ...函数体... 

             }  

        语法三:  function f_name () {

                    ...函数体... 

             } 
       函数的定义和使用:可在交互式环境下定义函数 

                可将函数放在脚本文件中作为它的一部分 

                可放在只包含函数的单独文件中 

          调用:函数只有被调用才会执行 

          调用:给定函数名  函数名出现的地方,会被自动替换为函数代码 函数的生命周期:被调用时创建,返回时终止

信号捕捉trap

  11)trap '触发指令' 信号    

        进程收到系统发出的指定信号后,将执行自定义指令,而不会执行原操作

     trap '' 信号    

        忽略信号的操作

     trap '-' 信号    

        恢复原信号的操作

     trap -p    

        列出自定义信号操作

     trap finish EXIT     

        当脚本退出时,执行finish函数

数组

  12)变量:存储单个元素的内存空间 

     数组:存储多个元素的连续的内存空间,相当于多个变量的集合 

     数组名和索引 

        索引:编号从0开始,属于数值索引 

        注意:索引可支持使用自定义的格式,而不仅是数值格式,即为关联索引, bash4.0版本之后开始支持 

         bash的数组支持稀疏格式(索引不连续) 

     声明数组: 

        declare -a ARRAY_NAME 

        declare -A ARRAY_NAME  

        关联数组  注意:两者不可相互转换

  13)数组赋值

      数组元素的赋值 

          (1) 一次只赋值一个元素 

            ARRAY_NAME[INDEX]=VALUE  weekdays[0]="Sunday"  weekdays[4]="Thursday" 

          (2) 一次赋值全部元素 

            ARRAY_NAME=("VAL1" "VAL2" "VAL3" ...) 

          (3) 只赋值特定元素 

            ARRAY_NAME=([0]="VAL1" [3]="VAL2" ...) 

          (4) 交互式数组值对赋值  

            read -a ARRAY 

      显示所有数组:declare  -a 

   14)引用数组元素  ${ARRAY_NAME[INDEX]}  注意:省略[INDEX]表示引用下标为0的元素 

    引用数组所有元素  ${ARRAY_NAME[*]}  ${ARRAY_NAME[@]} 

    数组的长度(数组中元素的个数)  ${#ARRAY_NAME[*]}  ${#ARRAY_NAME[@]}

   删除数组中的某元素:导致稀疏格式  unset ARRAY[INDEX] 

    删除整个数组  unset ARRAY

字符串切片 

  15) ${#var}:返回字符串变量var的长度 

    ${var:offset}:返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,到后的 部分,offset的取值在0 到                        ${#var}-1 之间(bash4.2后,允许为负值) 

    ${var:offset:number}:返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始, 长度为number的部分                ${var: -length}:取字符串的右侧几个字符 注意:冒号后必须有一空白字符 

    ${var:offset:-length}:从左侧跳过offset字符,一直向右取到距离右侧lengh个字符之前的内容 

    ${var: -length:-offset}:先从右侧向左取到length个字符开始,再向右取到距离右侧offset个字符之 间的内容

字符串处理

  16)基于模式取子串

       ${var#*word}:其中word可以是指定的任意字符    

         功能:自左而右,查找var变量所存储的字符串中,第一次出现的word, 删除字符串开头至第一次出现word字 符串(含)之间的所有字符    

       ${var##*word}:同上,贪婪模式,不同的是,删除的是字符串开头至后一次由word指定的字符之间的所有内容
 
       ${var%word*}:其中word可以是指定的任意字符    

         功能:自右而左,查找var变量所存储的字符串中,第一次出现的word, 删除字符串后一个字符向左至第一 次出现word字符串(含)之间的所有字符    

      file="/var/log/messages"    

      ${file%/*}: /var/log ${var%%word*}:同上,只不过删除字符串右侧的字符向左至后一次出现word字符之间的所有字符
 
    查找替换
 
      ${var/pattern/substr}:查找var所表示的字符串中,第一次被pattern所匹配到的字符串,以substr替换之                              ${var//pattern/substr}: 查找var所表示的字符串中,所有能被pattern所匹配到的字符串,以substr替换之                            ${var/#pattern/substr}:查找var所表示的字符串中,行首被pattern所匹配到的字符串,以substr替换之                                ${var/%pattern/substr}:查找var所表示的字符串中,行尾被pattern所匹配到的字符串,以substr替换之
 
    查找并删除
 
      ${var/pattern}:删除var表示的字符串中第一次被pattern匹配到的字符串

      ${var//pattern}:删除var表示的字符串中所有被pattern匹配到的字符串

      ${var/#pattern}:删除var表示的字符串中所有以pattern为行首匹配到的字符串

      ${var/%pattern}:删除var所表示的字符串中所有以pattern为行尾所匹配到的字符串
 
    字符大小写转换
 
        ${var^^}:把var中的所有小写字母转换为大写    

      ${var,,}:把var中的所有大写字母转换为小写

高级变量用法-有类型变量

  17)Shell变量一般是无类型的,但是bash Shell提供了declare和typeset两个命令 用于指定变量的类型,两个命令是等价的

     declare [选项] 变量名

        -r 声明或显示只读变量

        -i 将变量定义为整型数

        -a 将变量定义为数组

        -A 将变量定义为关联数组

        -f 显示已定义的所有函数名及其内容

        -F 仅显示已定义的所有函数名

        -x 声明或显示环境变量和函数

        -l  声明变量为小写字母  declare –l var=UPPER

        -u  声明变量为大写字母 declare –u var=lower

eval

  18)eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令。该命令适用于那些一次扫描无法实现其功能的 变量.该命令对变量进行两次扫描

expect命令

    19)expect 语法:expect [选项] [ -c cmds ] [ [ -[f|b] ] cmdfile ] [ args ] 
 
      -c:从命令行执行expect脚本,默认expect是交互地执行的    示例:expect -c 'expect "\n" {send "pressed enter\n"}                                 -d:可以输出输出调试信息  示例:expect -d ssh.exp

    expect中相关命令

        spawn 启动新的进程    

        send 用于向进程发送字符串    

        expect 从进程接收字符串    

        interact 允许用户交互    

        exp_continue 匹配多个字符串在执行动作后加此命令

转载于:https://www.cnblogs.com/dengkui/p/11060885.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Shell脚本高级编程教程,希望对你有所帮助。 Example 10-23. Using continue N in an actual task: 1 # Albert Reiner gives an example of how to use "continue N": 2 # --------------------------------------------------------- 3 4 # Suppose I have a large number of jobs that need to be run, with 5 #+ any data that is to be treated in files of a given name pattern in a 6 #+ directory. There are several machines that access this directory, and 7 #+ I want to distribute the work over these different boxen. Then I 8 #+ usually nohup something like the following on every box: 9 10 while true 11 do 12 for n in .iso.* 13 do 14 [ "$n" = ".iso.opts" ] && continue 15 beta=${n#.iso.} 16 [ -r .Iso.$beta ] && continue 17 [ -r .lock.$beta ] && sleep 10 && continue 18 lockfile -r0 .lock.$beta || continue 19 echo -n "$beta: " `date` 20 run-isotherm $beta 21 date 22 ls -alF .Iso.$beta 23 [ -r .Iso.$beta ] && rm -f .lock.$beta 24 continue 2 25 done 26 break 27 done 28 29 # The details, in particular the sleep N, are particular to my 30 #+ application, but the general pattern is: 31 32 while true 33 do 34 for job in {pattern} 35 do 36 {job already done or running} && continue 37 {mark job as running, do job, mark job as done} 38 continue 2 39 done 40 break # Or something like `sleep 600' to avoid termination. 41 done 42 43 # This way the script will stop only when there are no more jobs to do 44 #+ (including jobs that were added during runtime). Through the use 45 #+ of appropriate lockfiles it can be run on several machines 46 #+ concurrently without duplication of calculations [which run a couple 47 #+ of hours in my case, so I really want to avoid this]. Also, as search 48 #+ always starts again from the beginning, one can encode priorities in 49 #+ the file names. Of course, one could also do this without `continue 2', 50 #+ but then one would have to actually check whether or not some job 51 #+ was done (so that we should immediately look for the next job) or not 52 #+ (in which case we terminate or sleep for a long time before checking 53 #+ for a new job).
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值