shell 脚本常用调试方法
曾经我刚开始学习 shell 脚本时,除了知道用 echo 输出一些信息外,并不知道其他方法,仅仅依赖 echo 来查找错误,比较难调试且过程繁琐、效率低下。本文介绍下我常用的一些 shell 脚本调试方法,希望能对 shell 的初学者有所帮助。
sh 命令调试选项(推荐)
| 选项 | 说明 |
|---|---|
| -c | 从-c后的字符串中读取命令。 |
| -n | 检查是否存在语法错误,但不会实际执行。 |
| -x | 将执行的每一条命令和结果依次打印出来。 |
| -v | 执行过的脚本命令打印到标准输出。 |
使用方法:
字符串读取脚本。
$ sh -c 'if [ 1 -lt 2 ];then echo "true"; else echo "false"; fi'
true
注:临时测试 shell 语法或者小段脚本时使用。
检查脚本是否存在语法错误。
$ sh -n daodaotest.sh
跟踪调试 shell 脚本,将执行的每一条命令结果依次打印出来。
$ sh -x daodaotest.sh
+ '[' 2 -lt 2 ']'
+ COUNT=3
+ PARAMETER=daodaotest
+ (( i = 1 ))
+ (( i <= 3 ))
+ echo '第 1 遍打印:daodaotest'
第 1 遍打印:daodaotest
+ (( i++ ))
+ (( i <= 3 ))
+ echo '第 2 遍打印:daodaotest'
第 2 遍打印:daodaotest
+ (( i++ ))
+ (( i <= 3 ))
+ echo '第 3 遍打印:daodaotest'
第 3 遍打印:daodaotest
+ (( i++ ))
+ (( i <= 3 ))
+ exit 0
跟踪调试 shell 脚本,将执行的每一条命令和结果依次打印出来。
$ sh -xv daodaotest.sh
#!/bin/bash
# 调试脚本示例
# 使用方法
usage() {
echo "Usage: sh $0 COUNT PARAMETER"
echo "\t COUNT 循环打印次数"
echo "\t PARAMETER 打印字符串"
echo "示例:"
echo "\t 1. 打印 daodaotest 2 次"
echo "\t sh $0 2 daodaotest"
}
# 判断参数
if [ $# -lt 2 ];
then
usage
exit 1
fi
+ '[' 2 -lt 2 ']'
# 打印次数
COUNT=$1
+ COUNT=3
# 打印字符串
PARAMETER=$2
+ PARAMETER=daodaotest
# 循环打印
for (( i = 1; i <= $COUNT; i++));
do
echo "第 $i 遍打印:$PARAMETER"
done
+ (( i = 1 ))
+ (( i <= 3 ))
+ echo '第 1 遍打印:daodaotest'
第 1 遍打印:daodaotest
+ (( i++ ))
+ (( i <= 3 ))
+ echo '第 2 遍打印:daodaotest'
第 2 遍打印:daodaotest
+ (( i++ ))
+ (( i <= 3 ))
+ echo '第 3 遍打印:daodaotest'
第 3 遍打印:daodaotest
+ (( i++ ))
+ (( i <= 3 ))
exit 0
+ exit 0
注:本人最常用-x参数,能解决 90% 的脚本调试问题。
set 方法
在脚本中用set命令。
set -xv表示启用;set +xv表示禁用。
使用方法:
$ cat daodaotest.sh
set -xv
..... 省略
set +xv
$ sh daodaotest.sh 2 daodaotest
# 使用方法
usage() {
echo "Usage: sh $0 COUNT PARAMETER"
echo "\t COUNT 循环打印次数"
echo "\t PARAMETER 打印字符串"
echo "示例:"
echo "\t 1. 打印 daodaotest 2 次"
echo "\t sh $0 2 daodaotest"
}
# 判断参数
if [ $# -lt 2 ];
then
usage
exit 1
fi
+ '[' 2 -lt 2 ']'
# 打印次数
COUNT=$1
+ COUNT=2
# 打印字符串
PARAMETER=$2
+ PARAMETER=daodaotest
# 循环打印
for (( i = 1; i <= $COUNT; i++));
do
echo "第 $i 遍打印:$PARAMETER"
done
+ (( i = 1 ))
+ (( i <= 2 ))
+ echo '第 1 遍打印:daodaotest'
第 1 遍打印:daodaotest
+ (( i++ ))
+ (( i <= 2 ))
+ echo '第 2 遍打印:daodaotest'
第 2 遍打印:daodaotest
+ (( i++ ))
+ (( i <= 2 ))
exit 0
+ exit 0
注: 在脚本非常复杂时,set可以进行局部调试,在需要调试的代码块前后设置即可。
工具
shellcheck
shell 脚本静态检查工具,可以帮助你写出刚好的脚本。
官网:https://www.shellcheck.net/
手册:https://github.com/koalaman/shellcheck
使用方法:
$ shellcheck daodaotest.sh
In daodaotest.sh line 8:
echo "\t COUNT 循环打印次数"
^---------------^ SC2028: echo may not expand escape sequences. Use printf.
In daodaotest.sh line 9:
echo "\t PARAMETER 打印字符串"
^------------------^ SC2028: echo may not expand escape sequences. Use printf.
In daodaotest.sh line 11:
echo "\t 1. 打印 daodaotest 2 次"
^-----------------------^ SC2028: echo may not expand escape sequences. Use printf.
In daodaotest.sh line 12:
echo "\t sh $0 2 daodaotest"
^---------------------^ SC2028: echo may not expand escape sequences. Use printf.
In daodaotest.sh line 28:
for (( i = 1; i <= $COUNT; i++));
^----^ SC2004: $/${} is unnecessary on arithmetic variables.
For more information:
https://www.shellcheck.net/wiki/SC2028 -- echo may not expand escape sequen...
https://www.shellcheck.net/wiki/SC2004 -- $/${} is unnecessary on arithmeti...
BASH Debugger
bashdb 是一个类 GDB 的调试工具,可以运行断点设置、变量查看等常见调试操作。
常用参数:
h:查看帮助。
help 命令:命令的具体信息。
n:执行下一条语句。
s n:单步执行 n 次。
b n:在行号 n 处设置断点。
c n:一直执行到行号 n 处。
l:显示上下文代码。
print:打印变量值,例如 print $COUNT。
finish:执行到程序最后或断点处。
q or exit:退出。
R:重新执行。
使用方法:
$ bashdb --debug daodaotest.sh
bash debugger, bashdb, release 5.0-1.1.2
Copyright 2002-2004, 2006-2012, 2014, 2016-2019 Rocky Bernstein
This is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
(/Users/jlh/tmp/daodaotest.sh:15):
15: if [ $# -lt 2 ];
# 执行下一条语句。
bashdb<0> n
(/Users/jlh/tmp/daodaotest.sh:22):
22: COUNT=$1
# 显示上下文代码。
bashdb<1> l
17: usage
18: exit 1
19: fi
20:
21: # 打印次数
22: => COUNT=$1
23: # 打印字符串
24: PARAMETER=$2
25:
26: # 循环打印
# 单步执行 3 次。
bashdb<2> s 3
(/Users/jlh/tmp/daodaotest.sh:27):
27: for (( i = 1; i <= $COUNT; i++));
((i <= 3))
bashdb<3> l
22: COUNT=$1
23: # 打印字符串
24: PARAMETER=$2
25:
26: # 循环打印
27: => for (( i = 1; i <= $COUNT; i++));
28: do
29: echo "第 $i 遍打印:$PARAMETER"
30: done
31:
# 打印 $COUNT 参数值
bashdb<4> print $COUNT
3
# 执行到最后
bashdb<5> finish
第 1 遍打印:daodaotest
第 2 遍打印:daodaotest
第 3 遍打印:daodaotest
Debugged program terminated normally. Use q to quit or R to restart.
# 退出
bashdb<6> q
bashdb: That's all, folks...
shell 脚本常用调试方法的更多相关文章
- Shell脚本的调试方法
Shell脚本的调试方法 Shell提供了一些用于调试脚本的选项,如下所示: -n 读一遍脚本中的命令但不执行,用于检查脚本中的语法错误 -v 一边执行脚本,一边将执行过的脚本命令打印到标 ...
- Shell脚本的调试技术
编程中必不可少的一点就是调试,Shell脚本以其强大的功能令人向往,当然,它的强大之处不只是体现在语言的实现功能上,更强大的是它的调试功能,下面,我将以实例讲解Shell脚本的调试技术. 下面是我所用 ...
- shell脚本常用技巧
shell脚本常用技巧 1.获取随机字符串或数字 ~]#echo $RANDOM | md5sum | cut -c 1-6 ~]#openssl rand -base64 4 | cut -c 1- ...
- shell脚本常用参数
shell 脚本 常用参数 #!/bin/sh # 在脚本第一行脚本头 # sh为当前系统默认shell,可指定为bash等shell sh -x # 执行过程 sh -n # 检查语法 (a=bbk ...
- VC的常用调试方法
前言 VS是非常强大的IDE,所以掌握VSVC的常用方法,将会使得我们找出问题解决问题事半功倍. 目录 VSVC的常用调试方法 前言 1. Watch窗口查看伪变量 2. 查看指针指向的一序列值 3. ...
- shell常用调试方法
检查语法 -n选项只做语法检查,而不执行脚本. sh -n script_name.sh 启动调试 sh -x script_name.s 进入调试模式后,Shell依次执行读入的语句,产生的输出中有 ...
- Shell 脚本常用命令
Shell脚本是Linux开发工作中常用的工具,但是我一直没有找到一个适合自己的简明扼要的HandBook.在工作过程中整理了一下,贴在这里已备查看. 1 Shell中的特殊符号 ...
- SHELL 脚本----常用的命令
一个很不错的bash脚本编写教程,至少没接触过BASH的也能看懂 建立一个脚本 Linux中有好多中不同的shell,但是通常我们使用bash (bourne again shell) 进行she ...
- shell脚本怎么调试
shell是Linux系统上常用的一种脚本语言.一般从事web后台开发的从业者,都会用到shell,因此shell调试也是一项必备的技能.本文教你如何进行shell脚本调试. 工具/原料 Linu ...
随机推荐
- 【攻防世界】open-source
难度系数: 3.0 题目来源: Pediy CTF 2018 题目描述:菜鸡发现Flag似乎并不一定是明文比较的 先用:PE查壳,发现没有
- 使用burp插件captcha-killer识别图片验证码
0x01 开发背景 说起对存在验证码的登录表单进行爆破,大部分人都会想到PKav HTTP Fuzzer,这款工具在前些年确实给我们带来了不少便利.反观burp一直没有一个高度自定义通杀大部分图片验证 ...
- .gitignore排除(不忽略)二级以上目录下的文件或目录
在.gitignore中,结合使用/*和!filename的语法,可以达到除特定文件或目录外全部忽略的目的.但当希望不忽略的文件或目录在二级或多级目录下时,如果这样写 /* !/sub/subsub/ ...
- Idea无法调出搜狗等中文输入法
在用户目录下的文件.xprofile 中添加一下内容 export GTK_IM_MODULE=fcitx export QT_IM_MODULE=fcitx export XMODIFIERS=“@ ...
- 切比雪夫低副瓣阵列设计 MATLAB
相控阵天线中,直线阵列作为重要的一种,有着极为广泛的应用.切比雪夫低副瓣阵列设计是一种典型的设计方法. 切比雪夫方法主要是实现低副瓣.窄波束: 其产生的核心如下: 我的理解:因为能量守恒,所有副瓣都一 ...
- Ubuntu 18.04 将gcc版本降级为5.5版本
Remark: Polynomial algebra 程序由于版本问题只能在gcc 5.0 版本运行, 而ubuntu更新会将gcc 更新到7.0版本,出现冲突(报错:如下) collect2: er ...
- Jmeter4.0接口测试之断言实战(六)
在接口测试用例中得有断言,没有断言的接口用例是无效的,一个接口的断言有三个层面,一个是HTTP状态码的断言,另外一个是业务状态码的断言,最后是某一接口请求后服务端响应数据的断言.在Jmeter中增加断 ...
- coding++:拦截器拦截requestbody数据如何防止流被读取后数据丢失
1):现在开发的项目是基于SpringBoot的maven项目,拦截器的使用很多时候是必不可少的,当有需要需要你对body中的值进行校验,例如加密验签.防重复提交.内容校验等等. 2):当你开开心心的 ...
- Win10下 VSCode配置LaTex环境
------------恢复内容开始------------ 环境:win10 软件:Tex Live, VSCode ,Sumatra Tex Live官网下载速度很慢,所以推荐使用清华镜像下载链接 ...
- Spring中应用的那些设计模式
设计模式作为工作学习中的枕边书,却时常处于勤说不用的尴尬境地,也不是我们时常忘记,只是一直没有记忆. 今天,我们就设计模式的内在价值做一番探讨,并以spring为例进行讲解,只有领略了其设计的思想理念 ...