shell 脚本常犯错误与错误诊断

变量使用

  • 使用 declare/typeset 声明变量类型:-a 数组、-i 整数、-x 环境变量、-r 不可更改,也不能 unset。注意,默认就是字符串,即使看起来好像给它赋予了一个整数常量。常犯的错误就是拿一个字符串变量与一个数值常量做比较:

    1
    2
    > count=3; [ count -eq 3 ]
    count: integer expression expected
  • 整数运算:var=$((运算表达式))。示例:

    1
    2
    3
    > a=3;b=4;res1=$((${a}*${b}));res2=$(( ${a} * ${b} ))
    > echo "res1 = $res1, res2 = $res2"
    res1 = 12, res2 = 12
  • 小数运算:使用 bc 命令。简单示例:

    1
    > echo "123.123*55.9" | bc

更详细的使用请参考:鸟哥私房菜-学习shell script-数值计算

  • 变量赋值时等号两边不能有空格。变量值中若有空格,可用单或双引号将其括起来。错误 示例:

    1
    2
    > myname = VBird
    > myname=VBird Tsai
  • 变量值中若包含特殊字符(如空格、$、\、”、’等),需使用转义字符 \ 将其转换为字面值。示例:

    1
    > shellmyname=VBird\ Tsai
  • 单引号与双引号的区别。单引号中的特殊字符表示其本身,无特殊含义;双引号中的特殊字符有特殊含义,例如 $ 表示先求取紧跟着的变量值。示例:

    1
    2
    3
    4
    > myname=kingkong; var='name is $myname'; echo $var
    name is $myname
    > myname=kingkong; var="name is $myname"; echo $var
    name is kingkong

逻辑判断

  • 判断表达式有两种:test 指令、[_操作数1_<运算符>_操作数2_]。[] 写法常和 if 语句一起使用,所以很常用,但也很容易出错:

    1. 省略空格导致错误。为了强调,这里用下划线表示空格,任何一个空格都不能省,否则报错。错误 示例:

      1
      2
      3
      4
      # 错误演示1
      > count=3; [$count == "3" ] && echo "count is 3"
      # 错误演示2
      > count=3; [ $count =="3" ] && echo "count is 3"

      正确示例:

      1
      2
      > count=3; [ $count == "3" ] && echo "count is 3"
      count is 3
    2. [] 内的变量未使用双引号括起来导致 too many arguments 错误。建议 [] 内的变量使用双引号括起来,常量使用单或双引号括起来。示例:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      > cat demo.sh
      #!/bin/bash

      name="VBird Tsai"

      if [ "${name}" == "VBird Tsai" ]; then
      echo "good!"
      fi

      if [ ${name} == "VBird Tsai" ]; then
      echo "bad!"
      fi

      > sh demo.sh
      good!
      demo.sh: line 9: [: too many arguments
  • 运算符 -eq、-ne、-gt、-lt、-ge、-le 用于比较两个数值;而 ==、!= 用于比较两个字符串是否一样。错误 示例:

    1
    2
    3
    4
    > count=3; [ count -eq 3 ]
    integer expression expected: count
    > count=3; test count -eq 3
    integer expression expected: count

指令的嵌套执行

  • 在执行指令的过程中,需要用到其他指令执行的结果时,可使用反单引号`或$()将提供结果的指令括起来。示例:
    1
    2
    3
    4
    # 查看内核版本。三条命令输出结果相同
    > version=$(uname -r); echo $version
    > version=`uname -r`; echo $version
    > uname -r

shell 脚本错误诊断

  • 不会执行脚本,仅检查语法问题:sh -n my_script.sh
  • 执行脚本前,先将脚本内容输出到屏幕上:sh -v my_script.sh
  • 将执行过程全部输出出来,这个很有用:sh -x my_script.sh

待处理

  1. 如何不添加 sh 前缀就可以直接执行一个 shell script?与 sh 有什么区别?
  2. 如何正确获取当前脚本所在的路径?
  3. 如果获取前一条命令的执行结果
  4. 一堆以 $ 开头的特殊表达式的具体含义
0%