1. 程式人生 > >Shell指令碼的簡單排錯法及除錯程式bashdb

Shell指令碼的簡單排錯法及除錯程式bashdb

Jboss 的研究稍有卡殼,那就來點基礎教程好了。

與眾多指令碼語言一樣,Shell 指令碼在執行時出錯是很常見的,最簡單的原因無外乎指令碼在編寫的過程中出現了語法錯誤或者不小心輸錯了命令等。找出指令碼中的錯誤是很重要的能力。比如,我經常不小心會把 echo 命令寫成了 ehco,那麼執行就會出現下面這種情況:

Shell
12 [
root@localhost~]# sh testtest:line2:ehco:commandnotfound

從報錯資訊很容易判斷出錯的原因是“命令不存在”。重新編輯這個檔案修改成 echo 就可以解決。如果只是語法或命令上的錯誤還是比較容易辨別的,但往往一些邏輯或演算法錯誤就不容易發現,因為語法正確且本身不會造成程式執行錯誤。比如說下面的指令碼,本來想連續 10 次做某些操作的,結果卻遲遲沒輸出。仔細觀察一下就知道是陷入了死迴圈。

Shell
123456 [root@localhost~]# cat test#!/bin/bashfor((i=10;i>0;i=i+1))do#run command theredone

如果在上面的迴圈中加入 echo 語句,就容易發現問題了。而如果是單次迴圈過快,根本來不及看就進入了下一次迴圈,那這時就可以加入 sleep 命令降低單次迴圈的速度,比如使用 sleep 2,單次迴圈就將延時 2s,給我們帶來足夠的觀察時間:

Shell
1234567 [root@localhost~]# cat test#!/bin/bashfor((i=10;i>0;i=i+1))do#run command thereecho"i=$i";done

為了更清晰的看到指令碼執行的過程,我們還可以藉助-x 引數來觀察指令碼的執行情況。比如上面的指令碼,我們使用-x 引數執行就可以發現,變數 i 的值一直在增加,且一直滿足 x>0 的條件,所以這是一個死迴圈。所以,我們只要將 i=i+1 修改成 i=i-1 即可。

Shell
1234567891011121314151617 [root@localhost~]# sh -x test+((i=10))+((i>0))+echoi=10i=10+sleep2+((i=i+1))+((i>0))+echoi=11i=11+sleep2+((i=i+1))+((i>0))+echoi=12i=12+sleep2[Ctrl+c]終止指令碼

Shell 本身並沒有提供更好的排錯工具,為了更加精細地除錯 Shell 指令碼,我們可以藉助第三方工具 bashdb。這是一個類似於 GDB 的指令碼除錯軟體,小巧而強大,具有這隻斷點、單步執行、觀察變數等功能。下載時請根據所使用的 bash 版本選擇相應的 bashdb,否則會提示因為版本不符合而無法安裝。

如下檢視 bash 版本:

Shell
123 [root@localhost~]# bash --versionGNU bash,version3.1.25(1)-release(x86_64-redhat-linux-gnu)Copyright(C)2005Free Software Foundation,Inc.
下載地址

如下安裝:

Shell
12345678 #第一步:在終端使用wget下載3.1版本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.gzcdbashdb-3.1-0.09#第三步:配置及編譯安裝./configuremake&&makeinstall

安裝完成後,我們便可以在終端使用 bashdb 命令了,改命令典型用法如下:

Shell
1 [root@localhost~]# bashdb --debug 指令碼名

常用引數:

Shell
1234567891011121314151617181920212223 一、列出程式碼和查詢程式碼類:l列出當前行以下的10-列出正在執行的程式碼行的前面10.回到正在執行的程式碼行w列出正在執行的程式碼行前後的程式碼/pat/向後搜尋patpat?向前搜尋pat二、Debug控制類:h幫助help命令得到命令的具體資訊q退出bashdbx算數表示式計算算數表示式的值,並顯示出來!!空格Shell命令引數執行shell命令使用bashdb進行debug的常用命令(cont.)三、控制指令碼執行類:n執行下一條語句,遇到函式,不進入函式裡面執行,將函式當作黑盒sn單步執行n次,遇到函式進入函式裡面b行號n在行號n處設定斷點del行號n撤銷行號n處的斷點c行號n一直執行到行號nR重新啟動當前除錯指令碼Finish執行到程式最後condnexpr條件斷點