trap 命令

基本格式: trap command sig1 sig2 ... sigN
    有3种信号可以捕获:
    EXIT : 从函数中退出, 或整个脚本执行完毕
    ERR:   当一条命令返回非0状态码, 即命令执行不成功
    DEBUG: 脚本汇总每一条命令执行前

演示 DEBUG (一般使用这个方法查看整个程序的所有执行情况)

#!/bin/bash
    trap 'echo "before execute line:$LINENO, a=$a,b=$b,c=$c"' DEBUG    
    a=0
    b=2
    c=100
    while :
    do
        if ((a >= 10))
        then
            break
        fi
        let "a=a+2"
        let "b=b*2"
        let "c=c-10"
    done

运行结果如下:

演示: EXIT (一般使用这个方法来判断某一个函数是否成功执行)

#!/bin/bash
    
    func1()
    {
        echo "This is an correct function "
        var=2010
        return 0
    }
    trap 'echo "Line:$LINENO, var=$var"' EXIT #这个语句表示, 如果下边的fun1正确执行, 那么这里就显示 var=$var的值(20)
    fun1

演示: ERR

#!/bin/bash
    
    func2()
    {
        echo "This is an error function"
        var=2010
        return 1
    }
    trap 'echo "Line: $LINENO, var=$var"' ERR #这个语句表示, 如果下边的fun2是否为错误执行, 那么这里就显示 var=$var的值(20)
    func2

调试钩子

调试钩子源自于高级程序设计语言中的方法, 实际上是一个if/then结构代码块, DEBUG变量控制该代码块是否执行, 在程序开发调试阶段,
    讲DEBUG变量设置为TRUE, 使其输出调试信息, 到了程序交付使用阶段, 讲DEBUG设置为FALSE, 关闭调试钩子, 而无需一一删除调试钩子代码,
    if [ "$DEBUG" = "true" ]
    then
        echo "Debugging information"
    fi
    调试钩子中的DEBUG是一个全局变量, 在开发调试阶段, 可以利用export DEBUG=true 命令将DEBUG设置为true, 如果在每一处都需要输出调试
    信息的地方均使用if/then结构来判断DEBUG变量的值, 显的比较繁琐, 我们可以通过定义一个DEBUG函数使植入调试钩子的过程更为简洁:
    #!/bin/bash
    DEBUG()
    {
        if [ "$DEBUG" = "true" ]
        then
            $@
        fi
    }
    执行脚本前, 先 export DEBUG=true, 然后执行./脚本名

使用shell选项 (跟我之前知道几乎一样)

sh -n 脚本名 : 读取脚本中的命令, 进行语法检查, 但是并执行这些命令
    sh -x 在执行每个命令之前, 讲每个命令打印到标准输出(好用, 首选调试工具, 一般与trap的DEBUG共同使用, 这样既可以输出实际执行的每一行命令, 又
        可以逐行跟踪变量的值, 而且trap与这个-x都是在标准输出, 所以自动配合的非常好)
        -x 选项以 "+"符号作为提示符表示调试信息, 显得美中不足, 如果提示符能包含一些重要信息, 对调试更有帮助, 那么, 我们能否定制-x选项的提示符呢?
        答案是肯定的.
        LINENO 表示shell脚本的行号
        FUNCNAME 数组变量, 表示整个调用链上所有的函数名
        PS4 设置-x选项的提示符, 默认是"+"符号
        我们可以通过设置PS4, 使得-x选项提示符能包含LINENO和FUNCNAME等丰富的信息, 例如:

(下图是 sh-x 与 trap DEBUG 一起使用)

例如:

#!/bin/bash
        
        isroot()
        {
            if [ "$UID" -ne 0 ]
            then
                return 1
            else
                return 0
            fi
        }
        
        echoroot()
        {
            isroot
                if [ "$?" -ne 0 ]
                then
                    echo "I am not root user!"
                else
                    echo "root user!"
                fi
        }

export PS4='+{$LINENO:${FUNCNAME[0]}:${FUNCNAME[1]}}' #这里的PS4是, 显示本行号, 当前函数名, 调用当前函数的函数名
        exchoroot

(下图只是展示 PS4, 没有设置 trap DEBUG 功能)

16 shell调试技术的更多相关文章

  1. 【转】Linux Shell脚本调试技术

    本文转载自:https://www.ibm.com/developerworks/cn/linux/l-cn-shell-debug/ Shell脚本调试技术 本文全面系统地介绍了shell脚本调试技 ...

  2. shell脚本调试技术_转

    转自:http://itlab.idcquan.com/linux/SHELL/727128.html 参考:https://linux.cn/article-8045-1.html 本文全面系统地介 ...

  3. Shell脚本调试技术

    http://www.ibm.com/developerworks/cn/linux/l-cn-shell-debug/ 一. 前言 shell编程在unix/linux世界中使用得非常广泛,熟练掌握 ...

  4. Shell脚本的调试技术

    编程中必不可少的一点就是调试,Shell脚本以其强大的功能令人向往,当然,它的强大之处不只是体现在语言的实现功能上,更强大的是它的调试功能,下面,我将以实例讲解Shell脚本的调试技术. 下面是我所用 ...

  5. [转载]Android开发常用调试技术记录

    ANDROID 调试技术: 1)Ps 指令 ls –l /proc/27/ cat /proc/27/cmdline       #cmdline文件表示了这个进程所在的命令行. cat /proc/ ...

  6. (转)shell调试方法

    ---恢复内容开始--- 转载:https://www.ibm.com/developerworks/cn/linux/l-cn-shell-debug/ Shell脚本调试技术 曹 羽中2007 年 ...

  7. 掌握 Linux 调试技术

    掌握 Linux 调试技术 在 Linux 上找出并解决程序错误的主要方法 Steve Best (sbest@us.ibm.com)JFS 核心小组成员,IBM 简介: 您可以用各种方法来监控运行着 ...

  8. iOS 开发者旅途中的指南针 - LLDB 调试技术

    文章转载于:iOS 开发者旅途中的指南针 - LLDB 调试技术 今天给大家介绍的内容,无关乎任何功能性开发技术,但又对开发的效率影响至深,这就是调试技术. 何为调试呢,比如我们用 print 函数在 ...

  9. Linux kprobe调试技术使用

    kprobe调试技术是为了便于跟踪内核函数执行状态所设计的一种轻量级内核调试技术. 利用kprobe技术,可以在内核绝大多数函数中动态插入探测点,收集调试状态所需信息而基本不影响原有执行流程. kpr ...

随机推荐

  1. java中方法的参数传递机制(值传递还是引用传递)

    看到一个java面试题: 问:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?  答:是值传递.Java 编程语言只有值传递参 ...

  2. python 入门教程

    转载自:http://www.crifan.com/files/doc/docbook/python_beginner_tutorial/release/html/python_beginner_tu ...

  3. 使用System.arraycopy()实现数组之间的复制

    System提供了一个静态方法arraycopy(),我们可以使用它来实现数组之间的复制. 其函数原型是: public static void arraycopy(Object src, int s ...

  4. app缓存设计-文件缓存

    采用缓存,可以进一步大大缓解数据交互的压力,又能提供一定的离线浏览.下边我简略列举一下缓存管理的适用环境: 1. 提供网络服务的应用 2. 数据更新不需要实时更新,哪怕是3-5分钟的延迟也是可以采用缓 ...

  5. android pbap client 蓝牙

    一.  简介: 此功能具体使用的是bluetoothV2.1之后的Phone Book Access Profile功能,简称PBAP .目前MTK Android中只实现了server端的功能,并没 ...

  6. 单片机C语言开发学习笔记---动态的数码管

    在郭天祥的那本书中,有一个通过按键控制数码管的例子,在运行这个例子的时候,我发现当按键按下的时候,第一位数码管会熄掉,这是为什么呢? 后来在网上找到了原因,当我按下按键不松开的时候,接下来要运行的代码 ...

  7. session和cookie的总结

    cookie在客户端保持,而session在服务器端保持.   1.cookie机制:   产生:服务器通过http协议的响应头,指示浏览器产生相应的cookie信息 使用:浏览器按照一定规则通过ht ...

  8. C语言中的const

    今天探讨const,首先来说是将变量常量化.为什么要将变量常量化,原因有诸多好处有诸多.比如可以使数据更加安全不会被修改! 但是这个词有几个点要注意,那就是他究竟修饰了谁? 1.const int a ...

  9. SqlSever基础 有over函数时,用as为新列起名

    镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...

  10. mongodb数据库设计原则

    1.一对很少  one-to-few  可以采用内嵌文档 person集合中 { name:'张三', age:20, address:[ {country:"中国",provin ...