• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    详解bash中的脚本调试机制

    以调试模式运行脚本

    通过bash -x <script>的方式可以在调试模式下运行整个脚本, bash会在在运行前打印出了每一行命令, 而且每行前面用+号表明命令的嵌套层数.

    > bash -x debug.sh 
    + echo 'First line'
    First line # 输出结果没有加号
    ++ date # 先执行命令替换 两个加号是因为该命令嵌套在echo中
    + echo 'Print datetime: Thu 26 Mar 2020 08:21:28 PM CST Done.'
    Print datetime: Thu 26 Mar 2020 08:21:28 PM CST Done.
    

    如果脚本比较复杂, 我们可以通过使用环境变量PS4配合调试用的内置变量用于输出更加详细的信息:

    > export PS4='+${BASH_SOURCE}:${LINENO}:${FUNCNAME[0]}: '
    > bash -x debug.sh 
    +debug.sh:3:: echo 'First line'
    First line
    ++debug.sh:4:: date
    +debug.sh:4:: echo 'Print datetime: Thu 26 Mar 2020 08:35:59 PM CST Done.'
    Print datetime: Thu 26 Mar 2020 08:35:59 PM CST Done.
    

    我们也可以使用trap的DEBUG关键字在解释执行每一行脚本之前执行指定的命令或函数:

    trap 'echo "VARIABLE-TRACE> \$variable = \"$variable\""' DEBUG
    variable=29
    let variable++
    let variable*=5
    exit 0
    
    # 输出如下
    VARIABLE-TRACE> $variable = ""
    VARIABLE-TRACE> $variable = "29"
    VARIABLE-TRACE> $variable = "30"
    VARIABLE-TRACE> $variable = "150"
    
    

    还可以使用trap的ERR关键字用于在解释出现错误时执行预设的操作, 例如打印出错的命令:

    trap 'echo $BASH_COMMAND' ERR
    

    但鉴于使用trap进行调试的执行效率过低, 建议在较为复杂的脚本中直接使用调试选项或者使用bashdb等调试工具.

    高级调试

    查看函数调用信息

    在函数中使用内置命令caller能够把函数的调用信息输出到stdout, 但要注意该命令必须在函数内部调用.

    #!/usr/bin/bash
    
    func1 () {
      for i in `seq 0 3`
      do
        echo -e "Level$i\t  `caller $i`"
      done
    }
    
    func2 () {
      func1
    }
    
    func3 () {
      func2
    }
    
    func3
    caller 0 # 必须在函数中调用 否则无输出
    exit 0

    运行该脚本可以得到以下输出:

    Level0      11 func2 call.sh  # func1 的直接调用者
    Level1      15 func3 call.sh  # 一层间接调用
    Level2      18 main call.sh   # 二层间接调用
    Level3      # 无输出 因为没有第三层调用

    局部调试

    可以通过set命令构造局部调试块,我们可以按照如下方式添加局部调试:

    set -x
    date
    set +x
    > bash script1.sh # 不需要添加调试参数
    The script starts now.
    
    + date
    Fri 28 Feb 2020 06:23:04 PM CST
    + set +x
    
    This is a string: black
    And this is a number: 9

    调试参数表

    短命令 长命令 效果
    set -f set -o noglob 对文件名停用元字符匹配
    set -v set -o verbose 打印输入的命令
    set -x set -o xtrace 命令行首打印+,执行出错会打印详细信息

    调试用的参数可以在运行中动态叠加或删除:

    > set -v
    > date
    date 
    Fri 28 Feb 2020 06:54:47 PM CST
    > set -x      # 参数可以累加
    date        # -v 的效果
    + date       # -x 的效果
    Fri 28 Feb 2020 06:55:37 PM CST
    > set +vx      # 取消参数
    set +vx
    

    通过使用-f选项可以显著减少脚本中的转义字符:

    > ls ?
    x86_64-pc-linux-gnu-library
    > set -f      # 停用元字符匹配
    > ls ?
    ls: cannot access '?': No such file or directory
    > touch ?
    > ls ?
    '?'
    > rm ?
    > set +f -x   # 选项 x 还可以用于显示详细错误信息
    > aaa
    + aaa
    + '[' -x /usr/lib/command-not-found ']'
    + /usr/lib/command-not-found -- aaa
    
    Command 'aaa' not found, did you mean:
    
     command 'aha' from deb aha (0.5-1)
     command 'jaaa' from deb jaaa (0.8.4-4)
     command 'aa' from deb astronomical-almanac (5.6-6)
    
    Try: sudo apt install <deb name>
    
    + return 127
    
    

    默认调试

    也可以直接在脚本第一行添加参数让脚本默认以调试模式启动:

    #!/bin/bash -xv

    还可以在可能出错的命令前用echo输出调试信息:

    echo "debug message: now attempting to start w command"; w # 用 ; 对要执行的命令排序
    echo "Variable VARNAME is now set to $VARNAME."

    设置选项辅助调试

    为了方便调试,我们可以使用set命令对bash的选项进行设置:

    > set -o # 查看所有选项的开关状态
    > set -o | grep xtrace
    xtrace     off
    > set -x # 等价于 set -o xtrace
    > set -o | grep xtrace 
    + grep --color=auto xtrace
    + set -o
    xtrace     on
    > set +x # 等价于 set +o xtrace
    + set +x
    > set -o | grep xtrace
    xtrace     off
    

    常用调试选项

    引用为定义变量时报错:

    > unset $VAR;echo $VAR
    
    > set -u # 等价于 set -o nounset
    > echo $var
    bash: var: unbound variable
    
    

    为防止误操作覆盖文件中的数据, 设置禁止重定向到已经存在的文件:

    > set -C # 等价于 set -o noclobber
    > touch test
    > date > test
    bash: test: cannot overwrite existing file
    

    设置不解析通配符:

    > set -f # 等价于 set -o noglob
    > touch *
    > ll *
    -rw-rw-r-- 1 remilia remilia 0 Mar 1 20:09 '*'
    
    

    到此这篇关于详解bash中的脚本调试机制的文章就介绍到这了,更多相关bash 脚本调试 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    上一篇:最好懂的HTTPS讲解
    下一篇:详解bash中的初始化机制
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    详解bash中的脚本调试机制 详解,bash,中的,脚本,调试,