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