使用shell 编写shell调试器

  1 #!/bin/bash
2
3 var=`date +%Y%m%d%H%M%S`.sh
4
5 #判断'(',')'是否匹配
6 function CheckYuan(){
7 #获得要编译的文件的行数
8 row=$(awk '
9 END { print FNR }' $1)
10 #i用于标记遍历编译文件行数
11 i=1
12 #用于记录全局的存储剩余{d的个数
13 symbleCount=0
14 #用于统计前i行的剩余{的个数
15 count=0
16 #遍历编译文件的每一行
17 while [ $i -le $row ] && [ $symbleCount -ge 0 ]
18 do
19 count=$( awk -v _count=$symbleCount -v _i=$i '
20 BEGIN {FS =""; OFS =" " }
21 {
22 if ( FNR == _i ) {
23 for (j=1;j<=NF;j++){
24 if ($j~/^[ \t]*\([ \t]*$/){
25 _count = _count +1;
26 }
27 else if ($j~/^[ \t]*\)[ \t]*$/){
28 if (_count >0){
29 _count = _count -1;
30 }
31 else
32 if (_count<=0){
33 _count=-1*_i;
34 }
35 }
36 }
37 }
38 }
39 END {print _count }
40 ' $1 )
41 #如果{的个数大于等于0
42 if [ $count -ge 0 ]
43 then
44 #如果全局变量统计的{值小于当前{的值,将当前行的{的值保存到数组line中
45 while [ ${symbleCount} -lt ${count} ]
46 do
47 line[$symbleCount]=$i
48 symbleCount=`expr $symbleCount + 1`
49
50 done
51 #如果当前系统保存的统计{的值的全局变量大于当前的{的统计值,则将当前的统计值置未当前值
52 if [ ${symbleCount} -gt ${count} ]
53 then
54 symbleCount=$count
55 fi
56 #如果当前统计值未-1,则将row的值付给i
57 elif [ $count -lt 0 ]
58 then
59 i=$row
60 symbleCount=-1
61 var=`expr $count \* {-1}`
62 echo " "
63 echo "++++++++++++++++++++++++++++++++++++++++++"
64 echo " 》语法错误:第$var行的')'没有匹配的'('《 "
65 echo "++++++++++++++++++++++++++++++++++++++++++"
66 echo " "
67 return `false`
68 fi
69 #遍历下一行
70 i=`expr $i + 1`
71 done
72
73 if [ $symbleCount -gt 0 ]
74 then
75 echo " "
76 echo "++++++++++++++++++++++++++++++++++++++++++"
77 echo " 》语法错误:第$line行的'('缺少配对的')'《"
78 echo "++++++++++++++++++++++++++++++++++++++++++"
79 echo " "
80 return `false`
81 fi
82 if [ $symbleCount -eq 0 ]
83 then
84 return `true`
85 fi
86
87 }
88
89 #查看‘{’,‘}’是否匹配
90 function CheckCode(){
91 #获得要编译的文件的行数
92 row=$(awk '
93 END { print FNR }' $1)
94 #i用于标记遍历编译文件行数
95 i=1
96 #用于记录全局的存储剩余{d的个数
97 symbleCount=0
98 #用于统计前i行的剩余{的个数
99 count=0
100 #遍历编译文件的每一行
101 while [ $i -le $row ] && [ $symbleCount -ge 0 ]
102 do
103 count=$( awk -v _count=$symbleCount -v _i=$i '
104 BEGIN {FS =""; OFS =" " }
105 {
106 if ( FNR == _i ) {
107 for (j=1;j<=NF;j++){
108 if ($j~/^[ \t]*{[ \t]*$/){
109 _count = _count +1;
110 }
111 else if ($j~/^[ \t]*}[ \t]*$/){
112 if (_count >0){
113 _count = _count -1;
114 }
115 else
116 if (_count<=0){
117 _count=-1*_i;
118 }
119 }
120 }
121 }
122 }
123 END {print _count }
124 ' $1 )
125 #如果{的个数大于等于0
126 if [ $count -ge 0 ]
127 then
128 #如果全局变量统计的{值小于当前{的值,将当前行的{的值保存到数组line中
129 while [ ${symbleCount} -lt ${count} ]
130 do
131 line[$symbleCount]=$i
132 symbleCount=`expr $symbleCount + 1`
133
134 done
135 #如果当前系统保存的统计{的值的全局变量大于当前的{的统计值,则将当前的统计值置未当前值
136 if [ ${symbleCount} -gt ${count} ]
137 then
138 symbleCount=$count
139 fi
140 #如果当前统计值未-1,则将row的值付给i
141 elif [ $count -lt 0 ]
142 then
143 i=$row
144 symbleCount=-1
145 var=`expr $count \* {-1}`
146 echo " "
147 echo "++++++++++++++++++++++++++++++++++++++++++"
148 echo " 》语法错误:第$var行的'}'没有匹配的'{'《 "
149 echo "++++++++++++++++++++++++++++++++++++++++++"
150 echo " "
151 return `false`
152 fi
153 #遍历下一行
154 i=`expr $i + 1`
155 done
156
157 if [ $symbleCount -gt 0 ]
158 then
159 echo " "
160 echo "++++++++++++++++++++++++++++++++++++++++++"
161 echo " 》语法错误:第$line行的'{'缺少配对的'}'《"
162 echo "++++++++++++++++++++++++++++++++++++++++++"
163 echo " "
164 return `false`
165 fi
166 if [ $symbleCount -eq 0 ]
167 then
168 return `true`
169 fi
170
171 }
172
173
174 function drop_var() {
175 awk -v var=$1 '
176 NR==FNR{
177 print
178 }END { print "rm",var }
179 ' h_xz.sh > h_rt.sh
180 }
181
182 #在源程序每行后加入debug_wait
183 function makets_debugs() {
184 awk -v name=$1 '
185 NR==FNR&&(NR==1){
186 a[NR]=$0
187 }NR>FNR{
188 print;
189 for (i in a){
190 if (!/^[ \t]*#/ && NF && $0!="}" && !/^[ \t]*if/ && !/^[ \t]*elif/ && !/[ \t]*while/) print a[i],name,FNR
191 }
192 }' h_file $1 > h_xz.sh
193 }
194
195 #在源程序中加入调试function
196 function makets_funs() {
197 awk '
198 NR==FNR&&(FNR>=3 && FNR<=215){
199 a[FNR]=$0
200 }NR>FNR{
201 if (FNR==2)
202 for (i=3;i<=215;i++) print a[i];
203 print
204
205 }' h_file h_rt.sh > h_xzz.sh
206 }
207
208 #为调试文件中的变量fileName赋源文件的名称
209 function give_name() {
210 awk -v name=$1 '
211 NR==FNR{
212 if (FNR==2)
213 print "fileName=" name;
214 print
215 }' h_xzz.sh > $var
216 }
217
218 #判断用户输入的文件是否存在
219 function is_exist() {
220 read name
221 while [ ! -e ${name} ] || [ -z ${name} ]
222 do
223 echo " "
224 echo "++++++++++++++++++++++++++++++++++++++++++"
225 echo "|+++++++++++ 输入exit结束任务 +++++++++++|"
226 echo "|+++ 文件名不存在或者为空,请重新输入 +++|"
227 echo "++++++++++++++++++++++++++++++++++++++++++"
228 echo " "
229 read name
230 if [ $name == "exit" ] && [ $name != "" ]
231 then
232 #echo "输入了exit"
233 return `false`
234 fi
235 done
236 return `true`
237 }
238
239 #主函数
240 function main() {
241 echo " "
242 echo "++++++++++++++++++++++++++++++++++++++++++"
243 echo "|+++++++++ 请输入源文件的名称 +++++++++++|"
244 echo "++++++++++++++++++++++++++++++++++++++++++"
245 echo " "
246 if is_exist
247 then
248 if CheckYuan $name
249 then
250 if CheckCode $name
251 then
252 makets_debugs $name
253 drop_var $var
254 makets_funs
255 give_name $name
256 rm h_xz.sh
257 rm h_rt.sh
258 rm h_xzz.sh
259 chmod u+x $var
260 echo " "
261 echo "++++++++++++++++++++++++++++++++++++++++++"
262 echo "|+++++++++++++++ 开始调试 +++++++++++++++|"
263 echo "++++++++++++++++++++++++++++++++++++++++++"
264 echo " "
265 ./$var
266 fi
267 fi
268 else
269 echo " "
270 echo "++++++++++++++++++++++++++++++++++++++++++"
271 echo "|+++++++++++++++ 结束任务 +++++++++++++++|"
272 echo "++++++++++++++++++++++++++++++++++++++++++"
273 echo " "
274 fi
275 }
276
277 main
  1 debug_wait
2
3 function allFile() {
4 awk '{print NR,$0}' $fileName
5 }
6
7 function main() {
8 echo " "
9 echo "++++++++++++++++++++++++++++++++++++++++++"
10 echo "|+++++++++++++++++输入提醒+++++++++++++++|"
11 echo "|+++++++++1、调试操作:debug ++++++++++|"
12 echo "|+++++++++(其他命令)、运行操作 ++++++++++|"
13 echo "++++++++++++++++++++++++++++++++++++++++++"
14 echo " "
15 echo -e "\033[31m (System)>>请键入命令(序号和命令均可):\033[0m\c"
16 read ORDER
17 #有问题:怎么两个条件并列
18
19 if [ "$ORDER" = "debug" ] || [ "$ORDER" = "1" ]
20 then
21 promptDialog
22 else
23 run
24 fi
25 }
26 function Lookhelp() {
27 echo " "
28 echo "++++++++++++++++++++++++++++++++++++++++++"
29 echo "|+++++++++++++++调试步骤命令+++++++++++++|"
30 echo "|+++++++ 1、设置断点:set ++++++++|"
31 echo "|+++++++ 2、单步调试:step ++++++++|"
32 echo "|+++++++ 3、跳转至下一断点:next ++++++++|"
33 echo "|+++++++ 4、查看变量:check ++++++++|"
34 echo "|+++++++ (其他命令)、结束调试 ++++++++|"
35 echo "++++++++++++++++++++++++++++++++++++++++++"
36 }
37 function promptDialog() {
38
39 #初始化
40 is_OneStep=0
41
42 if [ "$firstInter" = "0" ]
43 then
44 firstInter=1
45 echo "------------------------------------------"
46 allFile
47 echo "------------------------------------------"
48 echo " 所调试程序显示如上,请根据行号设置断点:"
49 echo " "
50 echo "++++++++++++++++++++++++++++++++++++++++++"
51 echo "|+++++++++++++++++友情提示+++++++++++++++|"
52 echo "|++++++++如需帮助请键入:help ++++++++|"
53 echo "++++++++++++++++++++++++++++++++++++++++++"
54 fi
55 echo " "
56 echo -e "\033[31m (System)>>请键入命令(序号和命令均可):\033[0m\c"
57 read COMMAND
58 echo " "
59 #帮助操作
60 if [ "$COMMAND" = "help" ]
61 then
62 Lookhelp
63 echo " "
64 echo -e "\033[31m (System)>>请键入命令(序号和命令均可):\033[0m\c"
65 read COMMAND
66 echo " "
67 fi
68 #设置断点操作
69 if [ "$COMMAND" = "set" ] || [ "$COMMAND" = "1" ]
70 then
71 set_point
72 #单步调试操作
73 elif [ "$COMMAND" = "step" ] || [ "$COMMAND" = "2" ]
74 then
75 oneStep
76 #跳转至下一断点操作
77 elif [ "$COMMAND" = "next" ] || [ "$COMMAND" = "3" ]
78 then
79 nextPoint
80 #查看变量操作
81 elif [ "$COMMAND" = "check" ] || [ "$COMMAND" = "4" ]
82 then
83 check
84 #结束调试操作
85 else
86 run
87 fi
88 }
89
90 function check() {
91 if [ $kkkk -eq 0 ]
92 then
93 echo " ?????您还未设置断点,请选设置断点????? "
94 set_point
95 fi
96 k=0
97 while [ $k -eq 0 ]
98 do
99 echo -e "\033[31m (System)>>请输入变量(输入exit退出):\033[0m\c"
100 read orderName
101 if [ "$orderName" = "exit" ]
102 then
103 return
104 else
105 echo -e "\033[0m 变量显示:$orderName : ${!orderName}\033[0m"
106 fi
107 done
108 }
109
110 #跳转至下一断点操作
111 function nextPoint() {
112 if [ $kkkk -eq 0 ]
113 then
114 echo " ?????您还未设置断点,请选设置断点????? "
115 set_point
116 fi
117 N=$point_count
118 }
119
120 #单步调试 事实上是不需要任何操作的
121 function oneStep() {
122 if [ $kkkk -eq 0 ]
123 then
124 echo " ?????您还未设置断点,请选设置断点????? "
125 set_point
126 fi
127 is_OneStep=1
128 }
129
130 #调试该行
131 function debug_wait() {
132 src=$1
133 line=$2
134 #返回0或1,$?表示返回的值,必须紧接下一行引用
135 is_break $1 $2
136 if [ $? -eq 1 ] || [ $is_OneStep -eq 1 ]
137 then
138 echo " "
139 echo -e "\033[31m 程序内容打印》》第 $line 行内容为:\033[0m\c"
140 display_src $src $line
141 promptDialog $line
142 fi
143 }
144
145 #显示行
146 function display_src() {
147 awk -v line=$2 '
148 {
149 if( FNR == line ){
150 print $0;
151 }
152 else{
153 next;
154 }
155 }
156 ' $1
157 }
158
159 #判断是否设置了断点
160 function is_break() {
161 c=0
162 while [ $c -lt ${point_count} ]
163 do
164 if [ "$1" = "${point_src[$c]}" ] && [ "$2" = "${point_line[$c]}" ]
165 then
166 return 1
167 fi
168 c=`expr $c + 1`
169 done
170 return 0
171 }
172
173 #运行
174 function run() {
175 point_count=0
176 }
177
178 #设置断点
179 function set_point() {
180 echo "++++++++++++++++++++++++++++++++++++++++++"
181 echo "|++++++++++++设置断点方法介绍++++++++++++|"
182 echo "|+++ 1、输入程序的行号,表示断点位置。+++|"
183 echo "|+++ 2、输入 0 表示设置断点结束。 +++|"
184 echo "++++++++++++++++++++++++++++++++++++++++++"
185 echo " "
186 N=1
187
188 echo -e "\033[31m (System)>>请输入第 $N 个断点位置:\033[0m\c"
189 read NUM
190 while [ $NUM -gt 0 ]
191 do
192 point_src[${point_count:-0}]=$fileName
193 point_line[${point_count:-0}]=$NUM
194 point_count=`expr ${point_count:-0} + 1`
195 N=`expr $N + 1`
196 echo -e "\033[31m (System)>>请输入第 $N 个断点位置:\033[0m\c"
197 read NUM
198 done
199 if [ "$N" -ne "0" ]
200 then
201 M=`expr $N - 1`
202 echo -e "\033[31m (您一共设定了个 $M 断点)\033[0m"
203 kkkk=1
204 else
205 echo -e "\033[31m (您未设置断点)"
206 fi
207
208 promptDialog
209 }
210
211 point_count=0
212 firstInter=0
213 is_OneStep=0
214 kkkk=0
215 main



posted @ 2011-12-13 12:58  zbz092050  阅读(330)  评论(0编辑  收藏  举报