如何在Linux或者Unix下調試Bash Shell腳本
來自我的郵箱:
我寫了一個 hello world 小腳本。我如何能調試運行在 Linux 或者類 UNIX 的系統(tǒng)上的 bash shell 腳本呢?
這是 Linux / Unix 系統(tǒng)管理員或新用戶最常問的問題。shell 腳本調試可能是一項繁瑣的工作(不容易閱讀)。調試 shell 腳本有多種方法。
您需要傳遞 -x 或 -v 參數,以在 bash shell 中瀏覽每行代碼。

如何在 Linux 或者 UNIX 下調試 Bash Shell 腳本
讓我們看看如何使用各種方法調試 Linux 和 UNIX 上運行的腳本。
-x 選項來調試腳本
用 -x 選項來運行腳本:
$ bash -x script-name$ bash -x domains.sh
使用 set 內置命令
bash shell 提供調試選項,可以打開或關閉使用 set 命令:
set -x: 顯示命令及其執(zhí)行時的參數。set -v: 顯示 shell 輸入行作為它們讀取的
可以在 shell 腳本本身中使用上面的兩個命令:
#!/bin/bashclear# turn on debug modeset -xfor f in *dofile $fdone# turn OFF debug modeset +xls# more commands
你可以代替 標準釋伴 行:
#!/bin/bash
用以下代碼(用于調試):
#!/bin/bash -xv
使用智能調試功能
首先添加一個叫做 _DEBUG 的特殊變量。當你需要調試腳本的時候,設置 _DEBUG 為 on:
_DEBUG="on"
在腳本的開頭放置以下函數:
function DEBUG(){[ "$_DEBUG" == "on" ] && $@}
現在,只要你需要調試,只需使用 DEBUG 函數如下:
DEBUG echo "File is $filename"
或者:
DEBUG set -xCmd1Cmd2DEBUG set +x
當調試完(在移動你的腳本到生產環(huán)境之前)設置 _DEBUG 為 off。不需要刪除調試行。
_DEBUG="off" # 設置為非 'on' 的任何字符
示例腳本:
#!/bin/bash_DEBUG="on"function DEBUG(){[ "$_DEBUG" == "on" ] && $@}DEBUG echo 'Reading files'for i in *dogrep 'something' $i > /dev/null[ $? -eq 0 ] && echo "Found in $i file"doneDEBUG set -xa=2b=3c=$(( $a + $b ))DEBUG set +xecho "$a + $b = $c"
保存并關閉文件。運行腳本如下:
$ ./script.sh
輸出:
Reading filesFound in xyz.txt file+ a=2+ b=3+ c=5+ DEBUG set +x+ '[' on == on ']'+ set +x2 + 3 = 5
現在設置 _DEBUG 為 off(你需要編輯該文件):
_DEBUG="off"
運行腳本:
$ ./script.sh
輸出:
Found in xyz.txt file2 + 3 = 5
以上是一個簡單但非常有效的技術。還可以嘗試使用 DEBUG 作為別名而不是函數。 
調試 Bash Shell 的常見錯誤
Bash 或者 sh 或者 ksh 在屏幕上給出各種錯誤信息,在很多情況下,錯誤信息可能不提供詳細的信息。
跳過在文件上應用執(zhí)行權限
當你 編寫你的第一個 hello world 腳本,您可能會得到一個錯誤,如下所示:
bash: ./hello.sh: Permission denied
設置權限使用 chmod 命令:
$ chmod +x hello.sh$ ./hello.sh$ bash hello.sh
文件結束時發(fā)生意外的錯誤
如果您收到文件結束意外錯誤消息,請打開腳本文件,并確保它有打開和關閉引號。在這個例子中,echo 語句有一個開頭引號,但沒有結束引號:
#!/bin/bash.......echo 'Error: File not found^^^^^^^missing quote
還要確保你檢查缺少的括號和大括號 {}:
#!/bin/bash.....[ ! -d $DIRNAME ] && { echo "Error: Chroot dir not found"; exit 1;^^^^^^^^^^^^^missing brace }...
丟失像 fi,esac,;; 等關鍵字。
如果你缺少了結尾的關鍵字,如 fi 或 ;; 你會得到一個錯誤,如 “XXX 意外”。因此,確保所有嵌套的 if 和 case 語句以適當的關鍵字結束。有關語法要求的頁面。在本例中,缺少 fi:
#!/bin/bashecho "Starting..."....if [ $1 -eq 10 ]thenif [ $2 -eq 100 ]thenecho "Do something"fifor f in $filesdoecho $fdone# 注意 fi 丟失了
在 Windows 或 UNIX 框中移動或編輯 shell 腳本
不要在 Linux 上創(chuàng)建腳本并移動到 Windows。另一個問題是編輯 Windows 10上的 shell 腳本并將其移動到 UNIX 服務器上。這將由于換行符不同而導致命令沒有發(fā)現的錯誤。你可以使用下列命令 將 DOS 換行轉換為 CR-LF 的Unix/Linux 格式 :
dos2unix my-script.sh
技巧
技巧 1 - 發(fā)送調試信息輸出到標準錯誤
[標準錯誤] 是默認錯誤輸出設備,用于寫所有系統(tǒng)錯誤信息。因此,將消息發(fā)送到默認的錯誤設備是個好主意:
# 寫錯誤到標準輸出echo "Error: $1 file not found"## 寫錯誤到標準錯誤(注意 1>&2 在 echo 命令末尾)#echo "Error: $1 file not found" 1>&2
技巧 2 - 在使用 vim 文本編輯器時,打開語法高亮
大多數現代文本編輯器允許設置語法高亮選項。這對于檢測語法和防止常見錯誤如打開或關閉引號非常有用。你可以在不同的顏色中看到。這個特性簡化了 shell 腳本結構中的編寫,語法錯誤在視覺上截然不同。高亮不影響文本本身的意義,它只為你提示而已。在這個例子中,我的腳本使用了 vim 語法高亮:
!如何調試 Bash Shell 腳本,在 Linux 或者 UNIX 使用 Vim 語法高亮特性]7
技巧 3 - 使用 shellcheck 檢查腳本
shellcheck 是一個用于靜態(tài)分析 shell 腳本的工具??梢允褂盟鼇聿檎?shell 腳本中的錯誤。這是用 Haskell 編寫的。您可以使用這個工具找到警告和建議。你可以看看如何在 Linux 或 類UNIX 系統(tǒng)上安裝和使用 shellcheck 來改善你的 shell 腳本,避免錯誤和高效。















 
 
 










 
 
 
 