調(diào)試shell腳本的關(guān)鍵在于使用bash -x和set -e。一、bash -x可查看每行命令及變量展開結(jié)果,便于定位問題,亦可在腳本首行添加#!/bin/bash -x啟用調(diào)試模式。二、set -e讓腳本遇錯即停,避免錯誤擴(kuò)散,但需臨時關(guān)閉時可用set +e再恢復(fù)。三、結(jié)合兩者效果更佳,既顯示執(zhí)行流程又及時終止錯誤,也可動態(tài)控制調(diào)試范圍以減少日志量。
寫shell腳本時,調(diào)試是個繞不開的環(huán)節(jié)。尤其是腳本邏輯復(fù)雜或運(yùn)行環(huán)境多變的時候,光靠打印echo信息效率太低。常用的調(diào)試方式就是用bash -x和set -e這兩個工具配合使用,能幫你快速定位問題。
一、用bash -x查看腳本執(zhí)行過程
bash -x 是最直觀的調(diào)試方式,它會在執(zhí)行腳本時把每一行命令以及變量展開后的結(jié)果都打印出來,適合用來觀察腳本實際是怎么跑的。
比如你有個腳本叫 test.sh,直接運(yùn)行:
bash -x test.sh
你會看到類似這樣的輸出:
+ echo 'Hello World' Hello World
前面的 + 表示當(dāng)前執(zhí)行的命令。這樣你就能看到哪一行出了問題,或者變量有沒有被正確替換。
如果你不想每次都加 -x,也可以在腳本第一行加上:
#!/bin/bash -x
這樣腳本一運(yùn)行就會自動進(jìn)入調(diào)試模式。
二、用set -e讓腳本出錯就退出
默認(rèn)情況下,Shell腳本遇到錯誤會繼續(xù)往下執(zhí)行,這有時會讓你誤以為整個流程是成功的,其實中間某個關(guān)鍵步驟已經(jīng)失敗了。
這時候可以用 set -e,它的作用是:一旦某條命令返回非0狀態(tài)碼(也就是出錯了),整個腳本立刻停止執(zhí)行。
用法很簡單,在腳本開頭加上:
#!/bin/bash set -e
比如你寫了這么一段:
rm /tmp/nonexistent_file.txt echo "File removed"
如果文件不存在,rm 會報錯但腳本還是會繼續(xù)輸出”File removed”。加上 set -e 后,腳本會在rm失敗時立即退出,避免后續(xù)邏輯出錯。
不過要注意的是,有些命令即使失敗也想繼續(xù)執(zhí)行,比如你想判斷某個命令是否存在:
if ! command -v some_tool >/dev/null; then echo "some_tool not found" fi
這種情況下要臨時關(guān)閉 -e,可以這樣寫:
set +e command -v some_tool >/dev/null result=$? set -e
這樣就不會因為命令失敗而中斷腳本。
三、結(jié)合使用更有效
單獨(dú)用 -x 可以看執(zhí)行流程,單獨(dú)用 -e 可以防止錯誤擴(kuò)散。兩者結(jié)合起來調(diào)試效果更好。
你可以同時啟用它們,比如:
#!/bin/bash -x set -e
或者在腳本中分開寫:
#!/bin/bash set -x set -e
這樣腳本運(yùn)行時既能看到每一步的執(zhí)行情況,又能在出錯時及時停下來。非常適合用于CI/CD腳本、部署腳本等對可靠性要求較高的場景。
有時候你只想在部分代碼段開啟 -e 或者 -x,也可以動態(tài)控制,比如:
set -x # 開啟調(diào)試 # 這里是一些關(guān)鍵操作 set +x # 關(guān)閉調(diào)試
這種方式可以減少日志量,只關(guān)注你想看的部分。
基本上就這些。調(diào)試Shell腳本不難,關(guān)鍵是用好工具,理清邏輯。bash -x和set -e雖然簡單,但搭配起來非常實用。