您的位置:时时app平台注册网站 > 彩世界网址 > Shell调节和测量检验彩世界网址

Shell调节和测量检验彩世界网址

2019-11-03 08:50

实验

# backup /etc/apt/sources.list
cp /etc/apt/sources.list /etc/apt/sources.list.bk1
# add one row on the file(/etc/apt/sources.list)'s end for install bashdb
vi /etc/apt/sources.list
deb http://ftp.de.debian.org/debian wheezy main
wq
# update install source
aptitude update
# install bashdb
aptitude install bashdb
# bash doc
# http://www.gnu.org/software/bash/manual/bashref.html
# debug linux sh
# cd the .sh file dir, debug x.sh by bashdb
bashdb $(pwd)/main.sh
# bashdb's buildin command list
bashdb<0> help
Available commands:
  action     condition  edit     frame    load     run     source  unalias  
  alias      continue   enable   handle   next     search  step    undisplay
  backtrace  debug      eval     help     print    set     step-   untrace  
  break      delete     examine  history  pwd      shell   step    up       
  clear      disable    export   info     quit     show    tbreak  watch    
  commands   display    file     kill     return   signal  trace   watche   
  complete   down       finish   list     reverse  skip    tty  
# list command
bashdb<1> help list
list[>] [LOC|.|-] [NUMBER] 
LOC is the starting location or dot (.) for current file and
line. Subsequent list commands continue from the last line
listed. Frame switching however resets the line to dot. LOC can be a
read-in function name or a filename and line number separated by a
colon, e.g /etc/profile:5
If NUMBER is omitted, use the LISTSIZE setting as a count. Use "set
listsize" to change this setting. If NUMBER is given and is less than
the starting line, then it is treated as a count. Otherwise it is
treated as an ending line number.
By default aliases "l>" and "list>" are set to list. In this case and
more generally when the alias ends in ">", rather than center lines
around LOC that will be used as the starting point.
Examples:
list .      # List centered around the curent frame line
list        # Same as above if the first time. Else start from where
            # we last left off.
list -      # list backwards from where we left off.
list> .     # list starting from the current frame line.
list  10 3  # list 3 lines centered around 10, lines 9-11
list> 10 3  # list lines 10-12
list  10 13 # list lines 10-13
list  10 -5 # list from lines to 5 lines before teh end of the file
list  /etc/profile:5  # List centered around line 5 of /etc/profile.
list  /etc/profile 5  # Same as above.
list usage  # list centered around function usage().
# 列出脚本源码-当前
l .
# 列出脚本源码-指定行数
l 0
# bashdb的命令和gdb兼容, 用gdb的命令就可以了
# n : 步过
# s : 步入
# 回车 : 执行上一条命令
# 打印变量
print $i_index
pr $i_index
# 指定行数下断点
break 18
# 用debian源提供的bashdb下断点有bug, continue后,断不下来
# 去官网上下载一个新的bashdb : https://sourceforge.net/projects/bashdb/files/bashdb/4.4-0.94/
tar xvf ./bashdb-4.4-0.94.tar.bz2
cd bashdb-4.4-0.94/
aptitude install autotools-dev
make clean
./configure
make
make check # 这步有2项通不过,不影响
# SKIP: test-file-with-spaces
# FAIL: test-sig
# SKIP: test-bug-loc
# FAIL: test-bug-set-e
aptitude remove bashdb
rm -rf /usr/share/bashdb/
make install
# 可以用新版bashdb重新调试脚本了
bashdb $(pwd)/main.sh
# 列出当前文件所有内容, 行数范围设置大点 从0~1000, 如果这个当前sh只有45行,就都显示全了
l 0 1000
# 对指定文件的指定行数下断点
break /home/dev/main.sh:35
# 对函数下断点
break func_show_title
# 继续 continue
c
# 断点列表
L
# 列出指定文件指定行数
l /home/dev/common/sh.prog_version:16
# 删除断点(指定断点号码, 用L命令看断点列表)
delete 1
# bashdb好像没有在调试中,设置变量值的控制语法
# 执行完一个函数或一个循环
finish
# 退出调试器
q
# 好像初步使用bashdb, 查的这些调试命令,已经够用了
# 看一本书上,人家调试就用echo 或 bash -x, 人家对脚本编程该有多熟练啊
# 如果是我,只有在没有条件的情况下才会用echo, 有利器为啥不用呢?

 

echo "done"

linux sh : bashdb的安装和初步使用,shbashdb

INFO() {

三.gdbserver使用
(1) 目标机中
    执行命令gdbserver 10.0.12.144:1234 test
    注意test在编译的时候是要加-g选项的
(2) 宿主机中
    gdb test
    再输入命令target remote 10.0.12.143:1234
    接下来就可以gdb的调试了
(3) 说明
    目标机IP:10.0.12.143
    宿主机IP: 10.0.12.144
    端口是随意指定的,只要两端保持一致就行了
    test程序两端也必须相同

前言

这周在学习linux脚本编程,调试时,用echo 或bash -x
检查语法用bash -n x.sh

在函数中,要用echo返回出参字符串,如果再用echo打印调试信息,将逻辑搞乱了。
当时就在想,linux工具这么强大,既然有gdb, 那就有脚本的调试器才对啊.

今天在看书时,看到了bashdb这个工具。
在debian下试过了,好使。
虽然没有gdb -tui 那么好使,也满意了。

bashdb中也有好多调试命令,进入bashdb后,用help命令可以看到命令列表。
对于脚本的初级调试,掌握几个命令就够用。

[tt.sh : 5] echo this is a test ?

echo "done"

下载点

bashdb-4.4-0.94.tar.bz2.7z

    [ $_loglevel -ge 1 ] && echo "ERROR: $1" >&2

CC=/opt/toolchain/arm-linux/bin/arm-linux-gcc 
../gdb-6.8/gdb/gdbserver/configure --host=arm-linux --without-included-regex --without-included-gettext

 

脚本obj-gdbserver/build内容如下:
#!/bin/sh

其输出如下:

../gdb-6.8/configure --target=arm-linux --enable-shared --prefix=/usr/src/arm/gdb/build-gdb --without-x --disable-gdbtk --disable-tui --without-included-regex --without-included-gettext
make

}

一.前言
嵌入式Linux系统中,应用开发过程中,很多情况下,用户需要对一个应用程序进行反复调试,
特别是复杂的程序。采用GDB方法调试,由于嵌入式系统资源有限性,一般不能直接在目标系统上进行调试,
通常采用gdb gdbserver的方式进行调试。 Gdbserver在目标系统中运行,gdb则在宿主机上运行。
目标系统必须包括gdbserver程序,宿主机也必须安装gdb程序。在此我们还不能直接采用linux
发行版自带的gdb,需要交叉编译gdb和gdbserver。

打印一些变量,或者提示信息。这应该是一个通用的方法了。在 BASH 里,我们可以简单的用 echo,或者 printf 来输出一些 log,或者加一些 loglevel 来过滤一些 log。

开始编译:
(1) cd obj-gdb
    ./build
(2) cd obj-gdbserver
    ./build
    这时会生成Makefile,修改Makefile如下
    LDFLAGS= -static
    然后make
(3) cd bin
    cp ../obj-gdb/gdb/gdb .
    cp ../obj-gdbserver/gdbserver .
    arm-linux-strip gdbserver
(4) 好了bin目录下就是最终编译出来的gdb gdbserver了

 

二.编译gdb和gdbserver工具
下载最新版本的gdb-6.8.tar.gz,可以到ftp://ftp.gnu.org/gnu/gdb下载.
准备好自己的工作目录,如下示
/home/user/gdb
            |--gdb-6.8
            |--obj-gdb
                    |--build
            |--obj-gdbserver
                    |--build
            |--bin
                    
脚本obj-gdb/build内容如下:
#!/bin/sh

BASH 又有什么调试手段呢?

# add color

  • set x

ERROR() {

[ $_loglevel -ge 1 ] && echo -e "\033[31m ERROR:\033[0m $1" >&2

 

[tt.sh : 10] echo $i ?

 

[tt.sh : 8] [ true ] ?

 

 

trap [-lp] [[arg] sigspec ...]

trap 'echo $BASH_COMMAND return err' ERR

[tt.sh : 10] echo $i ?

 

[tt.sh : 11] ((i )) ?

有的时候,由于传进来的参数带有一些特殊字符,导致 BASH 解析时不是按照我们预想的进行。这个时候,把 -x 打开,就能在命令执行前,把扩展后的命令打印出来。比如基于前面写的函数:

 

#!/bin/bash

这个脚本的输出如下:

[tt.sh : 8] [ true ] ?

 

 

tt.sh: line 6: UnknownCmd: command not found

 

    [ $_loglevel -ge 2 ] && echo "INFO: $1" >&2

echo this is a normal test

UnknownCmd return err

    exit 1

[tt.sh : 10] echo $i ?

set x

done

sigspec 包括 <signal.h> 中定义的各个 signal, EXIT,ERR,RETURN 和 DEBUG。

各个 signal 这里就不介绍了。EXIT 会在 shell 退出时执行指定的命令。若当前 shell 中有命令执行返回非零值,则会执行与 ERR 相关联的命令。而 RETURN 是针对 source 和 . ,每次执行都会触发 RETURN 陷阱。若绑定一个命令到 DEBUG,则会在每一个命令执行之前,都会先执行 DEBUG 这个 trap。这里要注意的是,ERR 和 DEBUG 只在当前 shell 有效。若想函数和子 shell 自动继承这些 trap,则可以设置 -T(DEBUG/RETURN) 和 -E(ERR)。

1

●Shell的调试

-x(xtrace) 选项会导致 BASH 在执行命令之前,先把要执行的命令打印出来。这个选项对调试一些命令错误很有帮助。

 

do

this is a test

 

2 set -x

echo "this is a normal echo"

 

echo this is a test

 ERR: this is a error log

1 echo/printf

 

或者,让脚本中命令出错时,把相应的命令打印出来:

UnknownCmd

 

set -x

 

 

trap "echo this is a exit echo" EXIT

 

这里的实现只是简单的加了一个 loglevel,其实可以把 log 输出到一个文件中,或者给 log 加上颜色。比如:

如果想全程打开 xtrace,可以在执行脚本的时候加 -x 参数。

为了方便调试,BASH 也提供了陷阱机制。这跟之前介绍的两种方法高级不少。我们可以利用 trap 这个内置命令来指定各个 sigspec 应该执行的命令。trap 的具体用法如下:

}

# redirect to file

while [ true ]

[tt.sh : 11] ((i )) ?

 INFO: this is a info log

DIE() {

  • INFO 'this is a info log'

  • '[' 2 -ge 2 ']'

  • echo -e '\033[32m INFO:\033[0m this is a info log'

然后就可以看到如下输出:

_loglevel=2

比如,下面的脚本会在退出时,执行echo:

i=0

3 trap/bashdb

2

    echo $i

    echo "Critical: $1" >&2

亦或者,让脚本的命令单步执行:

[tt.sh : 8] [ true ] ?

[tt.sh : 7] i=0 ?

 

    ((i ))

#!/bin/bash

[tt.sh : 11] ((i )) ?

#!/bin/bash

ERROR "this is a error log"

是不是有点意思了?其实有一个 bashdb 的开源项目,也是利用 trap 机制,模拟 gdb 做了一个 bash 脚本的调试器。它本身也是一个 bash 脚本。

  • ERROR 'this is a error log'

  • '[' 2 -ge 1 ']'

  • echo -e '\033[33m ERR:\033[0m this is a error log'

[ $_loglevel -ge 1 ] && echo "ERROR: $1" > /var/log/xxx_log.$BASHPID

 

0

INFO "this is a info log"

trap '(read -p "[$0 : $LINENO] $BASH_COMMAND ?")' DEBUG

this is a normal test

}

本文由时时app平台注册网站发布于彩世界网址,转载请注明出处:Shell调节和测量检验彩世界网址

关键词: