我們在使用unix-like系統時, shell程式設計是必不可少的, 在編寫shell指令碼的時候也不可避免會產生bug, 所以我們就需要學習shell指令碼的除錯方法.
何為直接除錯, 相信大家在編寫c/c++程式除錯時候都經常會在程式中加乙個printf用來輸出中間值達到除錯的效果. 當然, 在shell指令碼除錯的時候這種方式也是同樣適用的, 我們在程式中新增echo達到輸出中間值的效果, 這裡就不做過多的贅述.如下面這個指令碼
#!/bin/sh
mkdir file_dir
cd file_dir
for ((i=0;i<10;i++))
do file_name=file_$i.txt
touch $file_name
echo $file_name
done
shell 提供了幾種除錯引數
引數說明
應用-n
只讀取shell指令碼,但不實際執行
測試shell指令碼是否存在語法錯誤
-x進入跟蹤方式,顯示所執行的每一條命令
使shell在執行指令碼的過程中把它實際執行的每乙個命令列顯示出來
-c從strings中讀取命令
臨時測試一小段指令碼的執行結果
此命令是執行下敘的除錯命令(tee)的除錯**加上 -x 引數的結果, 執行每一條命令並列印出來
[yancykahn@desktop-vilijh9~/program/shell-script]$sh -x test06.sh
+ ifconfig eth0
+ grep inet addr
+ tee iptmp.txt
+ cut -d : -f 3
+ ipaddr=255.255.0.0
+ echo 255.255.0.0
255.255.0.0
在使用linux系統命令進行除錯時, 我們需要更改shell指令碼的源**, 進行除錯. 主要思想是在其中加入我們需要輸出的資訊, 這裡主要使用trap和tee命令
參考至文獻[1.]
參考至文獻[2.]
trap命令用於指定在接收到訊號後將要採取的動作,常見的用途是在指令碼程式被中斷時完成清理工作。當shell接收到sigspec指定的訊號時,arg引數(命令)將會被讀取,並被執行。
trap [-lp] [[arg] sigspec ...]
在除錯的時候我們使用trap命令時, 可以將命令簡化為:
trap 'command' signal //command 的引號是必須的
其中, signal 是要捕獲的訊號, command是捕獲到signal後要執行的命令. 我麼將trap命令寫到 shell 指令碼中. 根據捕獲到的訊號得到輸出或者執行某些命令. shell 指令碼在執行的過程中會產生偽訊號. 何為偽訊號, 偽訊號是有非系統產生的訊號, 即為偽訊號, 在這裡為 shell 產生的訊號
shell中的偽訊號:
訊號名何時產生
使用說明
exit
從乙個函式中退出或者整個指令碼執行結束
在函式退出或者指令碼終止時可以輸出想要跟蹤的變數值
err當乙個命令返回非零狀態時(命令執行失敗)
追蹤執行失敗的命令並輸出除錯資訊
debug
指令碼中的每一條命令執行前
可以實現相關變數的全程跟蹤
執行例項
捕獲err資訊
#/bin/sh
not_found_error()
foo1()
foo2()
trap 'not_found_error $lineno' err
foofoo1
foo2
捕獲debug資訊
#!/bin/sh
echo "debug begin"
trap 'echo [debug: $lineno] value d=$d, e=$e, f=$g' debug
a=1b=2
c=3for ((i=0;i<5;i++))
do d=`expr $d + $a`
e=`expr $e + $b`
f=`expr $f + $c`
done
echo "end"
> ### 2. tee >在shell指令碼中管道以及輸出輸出重定向使用很多, 在起作用下一些命令的執行結果可能就成了下一條命令的輸入, 因為使用管道和輸入輸出重定向, 所以中間的輸出我們是不可見的. 因為輸出不可見所以除錯就異常困難, tee命令可以幫助我們很好的去除錯這種shell指令碼 首先我們先複習一下管道和tee命令: *** 1. 管道是linux中很重要的一種通訊方式,是把乙個程式的輸出直接連線到另乙個程式的輸入. *** *** 2. tee命令用於將資料重定向到檔案,另一方面還可以提供乙份重定向資料的副本作為後續命令的stdin。簡單的說就是把資料重定向到給定檔案和螢幕上. ***
ls | tee file_name.txt //把ls命令執行的結果輸出在螢幕和file_name.txt檔案中
tee 除錯例項現在有如下指令碼想要獲得掩碼位址
ipaddr=`ifconfig eth0 | grep "inet addr" | cut ' ' : -f 3`
echo $ipaddr
輸出為
cut: : no such file or directory
cut: :: no such file or directory
我們並不知道具體**出了錯, 在程式中加入tee把資料引流出來, 我們看中間的資料有什麼問題
ipaddr=`ifconfig eth0 | grep "inet addr" | tee iptemp.txt| cut ' ' : -f 3`
echo $ipaddr
檢視中間輸出iptemp.txt的資料
inet addr:169.254.14.12 mask:255.255.0.0
我們發現他們中間是以製表符分割的, 所以講程式改為
ipaddr=`ifconfig eth0 | grep "inet addr" | cut -d : -f 3`
echo $ipaddr
正常輸出得到掩碼位址
255.255.0.0
## 4. debug巨集除錯 在c語言中我們經常使用debug巨集來進行除錯, 在shell指令碼同樣可以使用相同的思想進行除錯
if [ 「$debug」 = 「true」 ]; then
echo 「debugging info」 #此處可以輸出除錯資訊
fi
參考至文獻[3.]
// $# 是傳給指令碼的引數個數
// $0 是指令碼本身的名字
// $1 是傳遞給該shell指令碼的第乙個引數
// $2 是傳遞給該shell指令碼的第二個引數
// $@ 是傳給指令碼的所有引數的列表
// $* 是以乙個單字串顯示所有向指令碼傳遞的引數,與位置變數不同,引數可超過9個
// $$ 是指令碼執行的當前程序id號
// $? 是顯示最後命令的退出狀態,0表示沒有錯誤,其他表示有錯誤
[1.]
[2.]
[3.]
[4.]
Shell 指令碼除錯
除錯功能是每一門程式語言都應該實現的重要特性,每個系統程式設計師都應該了解bash的除錯選項 1.使用選項 x,啟動shell指令碼的跟蹤除錯功能,將執行的每一條命令和輸出的結果輸出 test.sh檔案 bin bash foriin do echo i done echo script execu...
除錯shell指令碼
遇見莫名其妙的錯誤,先dos2uinux指令碼。echo命令是最有用的除錯指令碼工具之一。一般在可能出現問題的指令碼前後加入echo命令 使用bash命令引數進行除錯 引數 n 不會執行該指令碼,僅查詢指令碼語法是否有問題,並給出錯誤提示。v 在執行指令碼時,先將指令碼的內容輸出到螢幕上然後執行指令...
shell 指令碼除錯
發表於 2016 4 27 0 03 30 1693 人閱讀 分類 shell 除錯功能是每一門程式語言都應該實現的重要特性,每個系統程式設計師都應該了解bash的除錯選項 1.使用選項 x,啟動shell指令碼的跟蹤除錯功能,將執行的每一條命令和輸出的結果輸出 test.sh檔案 bin bash...