初学Bash时, 我从未想过想过bash也能debug, 也从未想过去debug Bash脚本. 随着技术的增长, 写的脚本越来越复杂, 使用echo打印日志来调试脚本的方式越来越捉襟见肘了. 直到某天

通读了一遍Bash Reference Manual, 才发现Bash也是可以debug的. 下面就介绍三种debug Bash脚本的方式.

1. debug某个脚本

执行脚本有两种方式, 一是bash script.sh的方式, 二是./script.sh的方式. 通过第一种方式执行脚本时, 加上-x选项即可debug脚本.

输出的结果中, 以+开头的行就是debug输出的信息.

$ cat test.sh
#!/bin/bash echo "Time: $(date)"
echo "User: $USER"
echo "Home: $HOME" $ bash -x test.sh
++date
+echo 'Time: Mon 11 Jul 2022 11:29:37 PM CST'
Time: Mon 11 Jul 2022 11:29:37 PM CST
+echo 'User: wbourne '
User: wbourne
+echo 'Home: /home/wbourne '
Home: /home/wbourne

2. debug特定脚本

前面说过执行脚本有两种方式, 那如果是用第二种方式执行脚本如何debug呢? 修改脚本的shabang为bash -x即可. 每次执行脚本就会输出debug信息.

此方式适合debug某个特定的脚本, 而上面的第一种方式则适合debug任何脚本.

$ cat test.sh
#!/bin/bash -x echo "Time: $(date)"
echo "User: $USER"
echo "Home: $HOME" $ ./test.sh
++date
+echo 'Time: Mon 11 Jul 2022 11:32:52 PM CST'
Time: Mon 11 Jul 2022 11:32:52 PM CST
+echo 'User: wbourne '
User: wbourne
+echo 'Home: /home/wbourne '
Home: /home/wbourne

请注意: 如果修改脚本的shabang为bash -x, 又以bash script.sh的方式执行脚本, 会发生什么? 居然没有输出debug信息!!!

设置shabang表示设置一个默认解释器, 如果没有指定解释器才会使用shabang中写的解释器. 以bash script.sh的方式执行脚本则指定了解释器为bash, 所以不会有debug信息.

$ bash test.sh
Time: Mon 11 Jul 2022 11:32:12 PM CST
User: wbourne
Home: /home/wbourne

3. debug脚本某一部分

如果脚本比较长, 我们之关心其中一部分, 就可以使用Bash内置命令set来debug部分脚本.

set -x表示开启debug, set +x表示关闭debug

$ cat test.sh
#!/bin/bash echo "Time: $(date)"
set -x
echo "User: $USER"
set +x
echo "Home: $HOME" $ ./test.sh
Time: Mon 11 Jul 2022 11:33:43 PM CST
+echo 'User: wbourne '
User: wbourne
+set +x
Home: /home/wbourne

4. PS4

既然是debug, 那肯定要详细才好. 上述debug只不过是输出了变量值而已, 是不是可以显示更多信息? 当然是可以的, debug信息的提示符是环境变量PS4, 默认为+, 我们可以更改PS4的值, 使其输出脚本名, 函数名, 行数等更详细的信息

$ export PS4='+\e[01;32m[${BASH_SOURCE}:${FUNCNAME[0]}:${LINENO}]\e[00m'

$ bash -x test.sh
++[test.sh::3]date
+[test.sh::3]echo 'Time: Mon 11 Jul 2022 11:35:08 PM CST'
Time: Mon 11 Jul 2022 11:35:08 PM CST
+[test.sh::4]echo 'User: wbourne '
User: wbourne
+[test.sh::5]echo 'Home: /home/wbourne '
Home: /home/wbourne

5. 参考

Bash脚本debug攻略的更多相关文章

  1. Jmeter脚本录制攻略

    基于Apache JMeter(5.2.1) 首先在TestPlan里添加一个HTTP代理服务武器: 设置端口,在目标控制器里选择线程组. 在Chrome浏览器里设置代理: 点击启动按钮后,在浏览器登 ...

  2. Linux Shell脚本攻略 读书笔记

    Linux Shell脚本攻略 读书笔记 这是一本小书,总共253页,但内容却很丰富,书中的示例小巧而实用,对我这样总是在shell门前徘徊的人来说真是如获至宝:最有价值的当属文本处理,对这块我单独整 ...

  3. Linux Shell脚本攻略

    -Linux Shell脚本攻略 总结的来说,这本书很实践性和实用性强,都是给的具体的例子,直接可以在终端操作实践,比单纯只看不动手务实多了,另外就是,这本书涵盖的内容也比较广,从文本操作到服务器管理 ...

  4. 老李分享:《Linux Shell脚本攻略》 要点(八)

    老李分享:<Linux Shell脚本攻略> 要点(八)   1.打印进程 [root@localhost program_test]# ps -e | head  PID TTY     ...

  5. 老李分享:《Linux Shell脚本攻略》 要点(七)

    老李分享:<Linux Shell脚本攻略> 要点(七)   1.显示给定文件夹下的文件的磁盘适用情况 [root@localhost program_test]# du -a -h ./ ...

  6. 老李分享:《Linux Shell脚本攻略》 要点(六)

    老李分享:<Linux Shell脚本攻略> 要点(六)   1.打印网络接口列表 [root@localhost touch_more]# ifconfig | cut -c-10 | ...

  7. 老李分享:《Linux Shell脚本攻略》 要点(五)

    老李分享:<Linux Shell脚本攻略> 要点(五)   //1.打包.解包 [root@localhost program_test]# tar -cf output.tar 11. ...

  8. 老李分享:《Linux Shell脚本攻略》 要点(四)

    老李分享:<Linux Shell脚本攻略> 要点(四)   1.IP地址的正则表达式: [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} 2. ...

  9. 老李分享:《Linux Shell脚本攻略》 要点(三)

    老李分享:<Linux Shell脚本攻略> 要点(三)   1.生产任意大小的文件 [root@localhost dd_test]#[root@localhost dd_test]# ...

随机推荐

  1. Linux 查询 OS、CPU、内存、硬盘信息

    点击上方"开源Linux",选择"设为星标" 回复"学习"获取独家整理的学习资料! 一.前言 当我们接手了一台或者几台服务器的时候,首先我们 ...

  2. golang get process name by pid

    一个很好的问题:How golang to get process name by process id (pid)? 目前看来go api并没有提供通过pid获取进程名称的方法,可以通过 /proc ...

  3. ES6片段

    那些可能会忘记或不知所以然的点: 1. 2. 3. 4. 5. 6. /* 函数调用会在内存形成一个"调用记录",又称调用帧,保存调用位置和内存变量等信息. 如果在函数 A 的内部 ...

  4. sklearn机器学习实战-KNN

    KNN分类 KNN是惰性学习模型,也被称为基于实例的学习模型 简单线性回归是勤奋学习模型,训练阶段耗费计算资源,但是预测阶段代价不高 首先工作是把label的内容进行二值化(如果多分类任务,则考虑On ...

  5. Centos7上安装python3.7

    Centos7安装python3.7 由于python2和python3在很大程度上有些不同,因为需要,就以决定安装python3.x的版本,但由于Centos上自安装的就是pyhton2.6.所以在 ...

  6. Element UI DatePicker 时间跨度限制在同一个月内

    <el-date-picker :picker-options="pickerOptions" v-model="rangeTime" type=&quo ...

  7. C#实现登录功能(连接SQLServer数据库)

    本例使用C#实现一个简单的登录功能,分为用户和管理员两个角色登录. 效果图: 核心代码 login.cs private void button1_Click(object sender, Event ...

  8. SeataAT模式原理

    Seata架构 Seata将分布式事务理解为一个全局事务,它由若干个分支事务组成,一个分支事务就是一个满足ACID的本地事务. Seata架构中有三个角色: TC (Transaction Coord ...

  9. freeswitch使用mod_shout模块播放mp3

    概述 freeswitch 在对VOIP语音通话中,可以通过playback命令播放IVR语音文件. 默认情况下,freeswitch支持wav文件,也可以直接播放VOIP中常见编解码的G711文件. ...

  10. IIS7 网站发布常见报错问题解决方案汇总

    本文实例为大家分享了IIS7 网站发布常见问题,以及五种问题的解决方法,供大家参考,具体内容如下: 1.不是有效的Win32位应用程序 : 解决方案: 1).进入应用程序池=>选中网站=> ...