shell指令碼專家指南筆記#1.shell指令碼錯誤檢測
阿新 • • 發佈:2018-12-18
##
# 本文為《shell指令碼專家指南》一書的學習筆記。
##
1.1. shell跟蹤
使用set -x和set -v。僅在當前指令碼生效。
set -x # 開啟程式碼跟蹤。個人理解為,顯示當前執行的程式碼。
set +x # 關閉程式碼跟蹤。
set -v # 開啟程式碼冗餘。個人理解為,顯示當前走過的程式碼(不一定執行)。
set +v # 關閉程式碼冗餘。
關於set -x 和 set -v的差異,建議手動執行一遍,慢慢去體會。
可以直接set -xv 來同時啟用兩種追蹤方式。
#!/bin/bash
set -x
set -v
# set -xv
echo -n "Can you write device drivers? Input your answer : "
read answer
answer=`echo $answer | tr [a-z] [A-Z]`
if [ $answer = Y ]; then
echo "Wow, you must be very skilled."
else
echo "Neither can I, I'm just an example shell script."
fi
1.2. 關鍵位置輸出
在關鍵位置輸出,使用echo 和print 命令。
#!/bin/bash echo -n "Can you write device drivers? Input your answer : " read answer answer=`echo $answer | tr [a-z] [A-Z]` if [ $answer = Y ]; then echo "Wow, you must be very skilled." # this is the trace. echo "# answer : $answer" else echo "Neither than I, im just an example script." # this is the trace. echo "# answer : $answer" fi
1.3. 使用除錯層級
可以認為是'1.2關鍵位置輸出'方法的擴充套件,通過DEBUG變數,來控制是否輸出日誌。
#!/bin/bash
# 0 is no debug, 1 is on debug。
DEBUG=1echo -n "Can you write device drivers? Input your answer : "
read answer
answer=`echo $answer | tr [a-z] [A-Z]`
if [ $answer = Y ]; then
echo "Wow, you must be very skilled."
test $DEBUG = 1 && echo "# answer : $answer"
else
echo "Neither than I, im just an example script."
test $DEBUG = 1 && echo "# answer : $answer"
fi
另一種優化的方式,是通過DEBUG變數,來實現不同的除錯層級。
#!/bin/bash
# 0 is no debug, 1 or more is different debug level。
DEBUG=0
echo -n "Can you write device drivers? Input your answer : "
read answer
test $DEBUG -ge 2 && echo "# raw_answer : $answer"
answer=`echo $answer | tr [a-z] [A-Z]`
if [ $answer = Y ]; then
echo "Wow, you must be very skilled."
test $DEBUG -ge 1 && echo "# answer : $answer"
test $DEBUG -ge 2 && echo "## the man is very skilled."
else
echo "Neither than I, im just an example script."
test $DEBUG -ge 1 && echo "# answer : $answer"
test $DEBUG -ge 2 && echo "## I cannot write driver either."
fi
1.4. 使用函式
使用特定函式,判斷指定指令碼的返回值,如果不為0,則輸出告警資訊。
示例:編寫alert函式 alert.sh
#!/bin/bash
alert() {
# Usage : alert <$?> <object>
if [ $1 -ne 0 ]; then
echo "WARN $2 did not complete successfully." >&2
exit $1
else
echo "INFO $2 complete successflly." >&2
fi
}
#!/bin/bash
# export alert() function.
. ./alert.sh
# export DEBUG level.
DEBUG=1
echo -n "file to read : "
read file
cat $file
alert $? "read file $file"
echo "do sth"
示例:alert的高階形式,未定義DEBUG或未開啟DEBUG時,函式不執行。
如果開啟了DEBUG,當上個指令碼返回值不為0時,則列印報錯資訊。
如果DEBUG等級大於9,則指令碼直接退出。
#!/bin/bash
alert() {
local RETURN_CODE=$?
if [ -z $DEBUG ] || [ $DEBUG -eq 0 ]; then
return
fi
if [ $RETURN_CODE -ne 0 ]; then
echo "WARN $* failed with return code of $RETURN_CODE ." >&2
[ $DEBUG -gt 9 ] && exit $RETURN_CODE
fi
}
1.5. 步進
通過變數 STEP_THROUGH 來控制指令碼的步進執行。
示例:STEP_THROUGH 為1時,指令碼會在指定位置暫停等待輸入後繼續。
#!/bin/bash
STEP_THROUGH=1
echo "I'm ready to start."
echo "Running step 1..."
test $STEP_THROUGH = 1 && {
echo -n "# Press [ENTER] to continue..."; read x
}
echo "Running step 2..."
test $STEP_THROUGH = 1 && {
echo -n "# Press [ENTER] to continue..."; read x
}
echo "Running step 3..."
echo "job's down"
示例:步進與alert結合,並增加步進層級。
當步進為1時,遇到警告會暫停,當步進為2時,每次呼叫alert都會暫停。
#!/bin/bash
alert() {
local RETURN_CODE=$?
if [ -z $DEBUG ] || [ $DEBUG -eq 0 ]; then
return
fi
if [ $RETURN_CODE -ne 0 ]; then
echo "WARN $* failed with return code of $RETURN_CODE ." >&2
[ $DEBUG -gt 9 ] && exit $RETURN_CODE
test $STEP_THROUGH = 1 && {
echo -n "# Press [ENTER] to continue..."; read x
}
fi
test $STEP_THROUGH = 2 && {
echo -n "# Press [ENTER] to continue..."; read x
}
}
#!/bin/bash
# export alert() function.
. ./alert.sh
# export DEBUG level.
DEBUG=1
# export STEP_THROUGH level.
STEP_THROUGH=1
echo -n "file to read : "
read file
cat $file
alert "read file $file"
echo "do sth"