Shell脚本的简单排错法及调试程序bashdb


难度 中等

与众多脚本语言一样,Shell 脚本在执行时出错是很常见的,最简单的原因无外乎脚本在编写的过程中出现了语法错误或者不小心输错了命令等。找出脚本中的错误是很重要的能力。比如,我经常不小心会把 echo 命令写成了 ehco,那么执行就会出现下面这种情况:

[root@localhost ~]test: line 2: ehco: command not found

从报错信息很容易判断出错的原因是“命令不存在”。重新编辑这个文件修改成 echo 就可以解决。如果只是语法或命令上的错误还是比较容易辨别的,但往往一些逻辑或算法错误就不容易发现,因为语法正确且本身不会造成程序运行错误。比如说下面的脚本,本来想连续 10 次做某些操作的,结果却迟迟没输出。仔细观察一下就知道是陷入了死循环。

[root@localhost ~]#!/bin/bash
for ((i=10;i>0;i=i+1))
do
done

如果在上面的循环中加入 echo 语句,就容易发现问题了。而如果是单次循环过快,根本来不及看就进入了下一次循环,那这时就可以加入 sleep 命令降低单次循环的速度,比如使用 sleep 2,单次循环就将延时 2s,给我们带来足够的观察时间:

[root@localhost ~]#!/bin/bash
for ((i=10;i>0;i=i+1))
do
    echo "i=$i";
done

为了更清晰的看到脚本运行的过程,我们还可以借助-x 参数来观察脚本的运行情况。比如上面的脚本,我们使用-x 参数执行就可以发现,变量 i 的值一直在增加,且一直满足 x>0 的条件,所以这是一个死循环。所以,我们只要将 i=i+1 修改成 i=i-1 即可。

[root@localhost ~]# sh -x test
+ (( i=10 ))
+ (( i>0 ))
+ echo i=10i=10
+ sleep 2
+ (( i=i+1 ))
+ (( i>0 ))
+ echo i=11i=11+ sleep 2
+ (( i=i+1 ))
+ (( i>0 ))
+ echo i=12i=12
+ sleep 2
[Ctrl +c]终止脚本

Shell 本身并没有提供更好的排错工具,为了更加精细地调试 Shell 脚本,我们可以借助第三方工具 bashdb。这是一个类似于 GDB 的脚本调试软件,小巧而强大,具有这只断点、单步执行、观察变量等功能。下载时请根据所使用的 bash 版本选择相应的 bashdb,否则会提示因为版本不符合而无法安装。

如下查看 bash 版本:

[root@localhost ~]# bash --version
GNU bash, version 3.1.25(1)-release (x86_64-redhat-linux-gnu)Copyright (C) 2005 Free Software Foundation, Inc.

如下安装:

wget  http://ftp.jaist.ac.jp/pub/sourceforge/b/ba/bashdb/bashdb/3.1-0.09/bashdb-3.1-0.09.tar.gz
tar -zxvf  bashdb-3.1-0.09.tar.gz
cd  bashdb-3.1-0.09
./configure
make && make install

安装完成后,我们便可以在终端使用 bashdb 命令了,改命令典型用法如下:

常用参数:

l  列出当前行以下的 10 行
-  列出正在执行的代码行的前面 10 行
.  回到正在执行的代码行
w  列出正在执行的代码行前后的代码
/pat/ 向后搜索 
pat?pat?向前搜索 pat
#Debug 控制类:
h     帮助
help  命令 得到命令的具体信息
q     退出 
bashdbx     算数表达式 计算算数表达式的值,并显示出来使用 
bashdb 进行 debug 的常用命令(cont.)

#控制脚本执行类:
n   执行下一条语句,遇到函数,不进入函数里面执行,将函数当作黑盒
s n 单步执行 n 次,遇到函数进入函数里面
b   行号 n 在行号 n 处设置断点
del 行号 n 撤销行号 n 处的断点
c   行号 n 一直执行到行号 n 处
R   重新启动当前调试脚本
Finish 执行到程序最后
cond n expr 条件断点

文章作者: growdu
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 growdu !
  目录
分类导航
随笔3 AI29 计算机基础13 算法1 博客搭建7 ChatGPT2 集群63 计算机通信1 数据库59 数据库深入93 数据库93 Docker11 DPDK26 编辑工具4 Elasticsearch4 FAQ1 Go Web1 hometown2 编程语言16 人生11 网络9 Linux38 OPC1 openGauss4 页面12 PostgreSQL54 程序员自我修养1 协议11 stock1 存储5 成长之路1 工具20 视频作品1 VPP18 Vue13 Web1 代码示例11 BenchmarkSQL1 PostgreSQL 源码修炼之路14
最热文章
1
PostgreSQL 逻辑复制全链路:以一个真实事务为例,从 `INSERT` 到 `apply` 的源码级旅程
数据库🔥 2162
2
PostgreSQL 逻辑复制 Stream 执行逻辑源码级拆解:从 reorderbuffer 触发到订阅端落盘回放
数据库🔥 1765
3
PostgreSQL 行锁机制源码级深度拆解:4 种锁模式 + xmax + MultiXact 的完整链路
数据库🔥 1656
4
PostgreSQL reorderbuffer.c 函数级源码全集:5615 行 / 95 个函数的逐函数解析
数据库深入🔥 1650
5
PostgreSQL 目录快照源码级深度拆解:系统表读取的 MVCC 真相与失效机制
数据库🔥 1604
6
13 逻辑复制深入
数据库深入🔥 1570
7
0 Postgresql存储、索引及系统优化、主备切换
PostgreSQL🔥 1495
8
PostgreSQL 读一行数据源码级深度拆解:MVCC 在每个环节的落点
数据库🔥 1464
9
PostgreSQL WAL 记录类型完全指南:21 个 RMGR × 80+ 种记录的源码级拆解
数据库🔥 1431
10
一文读懂openguass dcf网络模块
集群🔥 1420
11
PostgreSQL 元数据存储机制:从磁盘文件到内存缓存,`pg_class` 撑起的整个系统表体系
数据库🔥 1411
12
openGauss 并行解码设计原理深度拆解:reader + 多 worker + CSN 三层架构的源码级剖析
数据库深入🔥 1344
13
逻辑复制源码分析
数据库深入🔥 1327
14
PostgreSQL 逻辑复制:catalog 改动、可见性判定与 xmin/xmax 推进全景
数据库深入🔥 1317
15
自托管服务全家桶:从原文方案到可复制实操手册
人生🔥 1278
16
PostgreSQL CREATE_REPLICATION_SLOT 端到端源码分析:从 SQL 到 snapbuild 状态机的完整链路(每个函数每个参数)
数据库深入🔥 1277
17
PostgreSQL syscache 模块源码深度拆解:CatCache 数据结构、LRU 哈希表、cache invalidation 全链路
数据库深入🔥 1216
18
PostgreSQL 18 内核数据结构全景:RangeVar 与 20+ 个核心数据结构源码级拆解
数据库🔥 1158
19
PostgreSQL 逻辑复制里 `RUNNING_XACTS` 写入机制与快照 `xmin / xmax / xip` 的演化:源码级深度拆解
数据库🔥 1119
20
PostgreSQL 分区表:从一行 `PARTITION BY` 到路由热路径的全链路拆解
数据库🔥 1094