当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 8 篇帖子 ] 
作者 内容
1 楼 
 文章标题 : [问题] 有没有Shell的调试器?
帖子发表于 : 2007-12-18 13:06 

注册: 2007-10-22 11:45
帖子: 5
送出感谢: 0 次
接收感谢: 0 次
有时候想查看Shell Scripts到底哪里出了问题,不知道怎么办?
我需要的是像GDB那样的,一步一步执行,能查看变量的调试器。


页首
 用户资料  
 
2 楼 
 文章标题 :
帖子发表于 : 2007-12-18 13:07 
头像

注册: 2006-07-02 11:16
帖子: 12522
地址: 廣州
送出感谢: 0 次
接收感谢: 8
我没见过..
插旗子吧


_________________
^_^ ~~~
要理解递归,首先要理解递归。

地球人都知道,理论上,理论跟实际是没有差别的,但实际上,理论跟实际的差别是相当大滴。


页首
 用户资料  
 
3 楼 
 文章标题 :
帖子发表于 : 2007-12-18 14:01 
头像

注册: 2006-04-12 20:05
帖子: 8495
地址: 杭州
送出感谢: 0 次
接收感谢: 8
shell一般都不会写得很复杂,你在可能会错的地方加echo嘛,就知道了.好像没有专门的调试器,呵呵.


_________________
关注我的blog: ε==3


页首
 用户资料  
 
4 楼 
 文章标题 :
帖子发表于 : 2007-12-18 14:13 
头像

注册: 2005-08-14 21:55
帖子: 58428
地址: 长沙
送出感谢: 4
接收感谢: 272
http://eexpress.blog.ubuntu.org.cn/2007/08/07/shellps4/


_________________
● 鸣学


页首
 用户资料  
 
5 楼 
 文章标题 :
帖子发表于 : 2007-12-18 14:18 
头像

注册: 2006-04-12 20:05
帖子: 8495
地址: 杭州
送出感谢: 0 次
接收感谢: 8
eexpress 写道:
http://eexpress.blog.ubuntu.org.cn/2007/08/07/shellps4/


是个思路,但是这个离调试器还是有点距离的吧 :lol:


_________________
关注我的blog: ε==3


页首
 用户资料  
 
6 楼 
 文章标题 :
帖子发表于 : 2007-12-18 14:20 
头像

注册: 2007-01-15 17:15
帖子: 3766
送出感谢: 0 次
接收感谢: 0 次
bs lsls 做广告 , cheat 行为

引用:
第29章. 调试


Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.
Brian Kernighan

Bash shell 没有自带调试器, 甚至没有任何调试类型的命令或结构. [1] 脚本里的语法错误或拼写错误会产生含糊的错误信息,通常这些在调试非功能性的脚本时没什么帮助.

例子 29-1. 一个错误的脚本

1 #!/bin/bash
2 # ex74.sh
3
4 # 这是一个错误的脚本.
5 # 哪里有错?
6
7 a=37
8
9 if [$a -gt 27 ]
10 then
11 echo $a
12 fi
13
14 exit 0

脚本的输出:

./ex74.sh: [37: command not found

上面的脚本有什么错误(线索: 注意if的后面)?

例子 29-2. 丢失关键字(keyword)

1 #!/bin/bash
2 # missing-keyword.sh: 会产生什么样的错误信息?
3
4 for a in 1 2 3
5 do
6 echo "$a"
7 # done # 第7行的必需的关键字 'done' 被注释掉了.
8
9 exit 0

脚本的输出:

missing-keyword.sh: line 10: syntax error: unexpected end of file


注意错误信息中说明的错误行不必一定要参考, 但那行是Bash解释器最终认识到是个错误的地方.

出错信息可能在报告语法错误的行号时会忽略脚本的注释行.

如果脚本可以执行,但不是你所期望的那样工作怎么办? 这大多是由于常见的逻辑错误产生的.

例子 29-3. test24, 另一个错误脚本

1 #!/bin/bash
2
3 # 这个脚本目的是为了删除当前目录下的所有文件,包括文件名含有空格的文件。
4 #
5 # 但不能工作.
6 # 为什么?
7
8
9 badname=`ls | grep ' '`
10
11 # 试试这个:
12 # echo "$badname"
13
14 rm "$badname"
15
16 exit 0

为了找出 例子 29-3 的错误可以把echo "$badname" 行的注释去掉. echo 出来的信息对你判断是否脚本以你希望的方式运行时很有帮助.

在这个实际的例子里, rm "$badname" 不会达到想要的结果,因为$badname 没有引用起来. 加上引号以保证rm 命令只有一个参数(这就只能匹配一个文件名). 一个不完善的解决办法是删除A partial fix is to remove to quotes from $badname and to reset $IFS to contain only a newline, IFS=$'\n'. 不过, 存在更简单的办法.

1 # 修正删除包含空格文件名时出错的办法.
2 rm *\ *
3 rm *" "*
4 rm *' '*
5 # Thank you. S.C.

总结该脚本的症状,

1. 终止于一个"syntax error"(语法错误)的信息, 或

2. 它能运行, 但不是按期望的那样运行(逻辑错误).

3.

它能运行,运行的和期望的一样, 但有讨厌的副作用 (逻辑炸弹).

用来调试不能工作的脚本的工具包括

1.

echo 语句可用在脚本中的有疑问的点上以跟踪了解变量的值, 并且也可以了解后续脚本的动作.
Tip

最好只在调试时才使用echo语句.

1 ### debecho (debug-echo), by Stefano Falsetto ###
2 ### 只有变量 DEBUG 设置了值时才会打印传递进来的变量值. ###
3 debecho () {
4 if [ ! -z "$DEBUG" ]; then
5 echo "$1" >&2
6 # ^^^ 打印到标准出错
7 fi
8 }
9
10 DEBUG=on
11 Whatever=whatnot
12 debecho $Whatever # whatnot
13
14 DEBUG=
15 Whatever=notwhat
16 debecho $Whatever # (这儿就不会打印了.)

2.

使用 tee 过滤器来检查临界点的进程或数据流.
3.

设置选项 -n -v -x

sh -n scriptname 不会实际运行脚本,而只是检查脚本的语法错误. 这等同于把 set -n 或 set -o noexec 插入脚本中. 注意还是有一些语法错误不能被这种检查找出来.

sh -v scriptname 在实际执行一个命令前打印出这个命令. 这也等同于在脚本里设置 set -v 或 set -o verbose.

选项 -n 和 -v 可以一块使用. sh -nv scriptname 会打印详细的语法检查.

sh -x scriptname 打印每个命令的执行结果, 但只用在某些小的方面. 它等同于脚本中插入 set -x 或 set -o xtrace.

把 set -u 或 set -o nounset 插入到脚本里并运行它, 就会在每个试图使用没有申明过的变量的地方打印出一个错误信息.
4.

使用一个"assert"(断言) 函数在脚本的临界点上测试变量或条件. (这是从C语言中借用来的.)

例子 29-4 用"assert"测试条件

1 #!/bin/bash
2 # assert.sh
3
4 assert () # 如果条件测试失败,
5 { #+ 则打印错误信息并退出脚本.
6 E_PARAM_ERR=98
7 E_ASSERT_FAILED=99
8
9
10 if [ -z "$2" ] # 没有传递足够的参数.
11 then
12 return $E_PARAM_ERR # 什么也不做就返回.
13 fi
14
15 lineno=$2
16
17 if [ ! $1 ]
18 then
19 echo "Assertion failed: \"$1\""
20 echo "File \"$0\", line $lineno"
21 exit $E_ASSERT_FAILED
22 # else
23 # return
24 # 返回并继续执行脚本后面的代码.
25 fi
26 }
27
28
29 a=5
30 b=4
31 condition="$a -lt $b" # 会错误信息并从脚本退出.
32 # 把这个“条件”放在某个地方,
33 #+ 然后看看有什么现象.
34
35 assert "$condition" $LINENO
36 # 脚本以下的代码只有当"assert"成功时才会继续执行.
37
38
39 # 其他的命令.
40 # ...
41 echo "This statement echoes only if the \"assert\" does not fail."
42 # ...
43 # 余下的其他命令.
44
45 exit 0

5.

用变量$LINENO和内建的caller.
6.

捕捉exit.

脚本中的The exit 命令会触发信号0,终结进程,即脚本本身. [2] 这常用来捕捉exit命令做某事, 如强制打印变量值. trap 命令必须是脚本中第一个命令.

捕捉信号

trap

当收到一个信号时指定一个处理动作; 这在调试时也很有用.
Note

信号是发往一个进程的非常简单的信息, 要么是由内核发出要么是由另一个进程, 以告诉接收进程采取一些指定的动作 (一般是中止). 例如, 按Control-C, 发送一个用户中断( 即 INT 信号)到运行中的进程.

1 trap '' 2
2 # 忽略信号 2 (Control-C), 没有指定处理动作.
3
4 trap 'echo "Control-C disabled."' 2
5 # 当按 Control-C 时显示一行信息.

例子 29-5. 捕捉 exit

1 #!/bin/bash
2 # 用trap捕捉变量值.
3
4 trap 'echo Variable Listing --- a = $a b = $b' EXIT
5 # EXIT 是脚本中exit命令产生的信号的信号名.
6 #
7 # 由"trap"指定的命令不会被马上执行,只有当发送了一个适应的信号时才会执行。
8 #
9
10 echo "This prints before the \"trap\" --"
11 echo "even though the script sees the \"trap\" first."
12 echo
13
14 a=39
15
16 b=36
17
18 exit 0
19 # 注意到注释掉上面一行的'exit'命令也没有什么不同,
20 #+ 这是因为执行完所有的命令脚本都会退出.


页首
 用户资料  
 
7 楼 
 文章标题 :
帖子发表于 : 2007-12-18 17:10 
头像

注册: 2007-03-13 17:26
帖子: 2254
送出感谢: 0 次
接收感谢: 1
配置变量
RED="\033[0;31m" ## "\[\033[0;31m\]"
GREEN="\033[0;32m"
ORANGE="\033[0;33m"
WHITE="\033[00m"
BOLD=$WHITE
export PS4="$GREEN+{$LINENO:${FUNCNAME[0]}}$WHITE"

运行脚本
bash -x ??.sh


页首
 用户资料  
 
8 楼 
 文章标题 :
帖子发表于 : 2008-01-10 0:34 

注册: 2008-01-10 0:02
帖子: 20
送出感谢: 0 次
接收感谢: 0 次
请google一下bashdb


_________________
welcome to my blog
http://guocongbin.iblog.com
http://blog.csdn.net/guocongbin


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 8 篇帖子 ] 

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 2 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译