1. 程式人生 > >shell指令碼專家指南筆記#1.shell指令碼錯誤檢測

shell指令碼專家指南筆記#1.shell指令碼錯誤檢測

## 
# 本文為《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"