這款利器幫你查找和修復 Linux Shell 腳本錯誤
什么是shellcheck?
如果您從事 Linux Bash 開發(fā)人員已有一段時間,您可能會在自己的腳本或其他人的腳本中發(fā)現大量錯誤。當我們開發(fā)代碼時,必然會在代碼中引入錯誤。即使是最優(yōu)秀的開發(fā)人員也可能偶爾會忽略代碼中不可預見的復雜性或警告。在 Bash 中,沒有像C++那樣的真正的編譯器。然而,有一組工具可以在開發(fā) Bash 腳本時提供很大幫助。比如 shellcheck。這個優(yōu)秀的實用程序將解析 Bash 腳本文件并根據分析過程中發(fā)現的內容提出建議。這有點像擁有了一個 Bash 編譯器。像 shellcheck 這樣的工具在操作上與其他運行時工具不同,例如執(zhí)行腳本??bash -x?
?以查看正在執(zhí)行的腳本中的每個命令,并且是實時的。原因是 shellcheck 將分析腳本(文件)而不實際執(zhí)行它,這與編譯器所做的再次相似。
安裝shellcheck
要在基于 Debian/Apt 的 Linux 發(fā)行版(如 Ubuntu 和 Mint)上安裝shellcheck,請在終端中執(zhí)行以下命令:
linuxmi@linuxmi:~/www.linuxmi.com$ sudo apt install shellcheck
要在基于 RedHat/Yum 的 Linux 發(fā)行版(如 RHEL、Centos 和 Fedora)上安裝shellcheck,請在終端中執(zhí)行以下命令:
linuxmi@linuxmi:~/www.linuxmi.com$ sudo yum install shellcheck
運行shellcheck
在安裝了 shellcheck 后,我們就可以用一個損壞的腳本做一個簡單的測試。首先我們定義我們的腳本??linuxmi.com.sh?
?如下:
echo 'Bash 不是 Hash
echo 為我回應更多錯誤www.linuxmi.com"
if [ -d ./linuxmi }; than
echo 'sure! < start
fif
你能找到多少bug?(提示:有 8 個!)。接下來讓我們看看 shellcheck 對這段代碼的影響:
linuxmi@linuxmi:~/www.linuxmi.com$ shellcheck linuxmi.sh
1、它立即在第一行發(fā)現shebang規(guī)范存在問題。我們的 shebang 這一行?
?#!/bin/hash?
?應該是??#!/bin/bash?
?。讓我們解決這個問題。問題 1/8 已修復!我們還將同時修復 shellcheck 立即識別的另外兩個問題:2、您是否忘記關閉這個單引號字符串?(Did you forget to close this single quoted string?),對于第二行:很準!問題 2/8 已修復。3、對于第三個問題,我們/開發(fā)人員對 shellcheck 的意圖有點混亂,這是可以預料的,因為第2 行打開了一個字符串,該字符串??'?
?僅在第 5 行看到另一個??'?
?時才終止!由于第三個問題是第二個問題的結果,因此這次運行將允許我們暫時修復兩個問題。我們的腳本現在看起來像這樣:
echo 'Bash 不是 Hash'
echo 為我回應更多錯誤www.linuxmi.com"
if [ -d ./linuxmi }; than
echo 'sure! < start
fif
在進行更正后,讓我們再次運行 shellcheck,看看輸出是什么。在這種情況下,shellcheck 看到一個 ?
?"?
?在第 3 行打開(即使它在行尾,它實際上是一個打開的雙引號),并且即使在腳本結尾(注意第 8 行的指示,這在我們的6行腳本中并不存在,在最后一行之后只有一個空行。讓我們清理這一空行,并修復第3行開頭的雙引號問題,現在可以很容易地理解。問題3/8已修復!我們的腳本現在看起來像這樣:
echo 'Bash 不是 Hash'
echo "為我回應更多錯誤www.linuxmi.com"
if [ -d ./linuxmi }; than
echo 'sure! < start
fif
重新運行 shellcheck(注意這些步驟與在其他編碼語言中使用編譯器有多么相似):再清楚不過了;提到的語法錯誤出現在這個 if 表達式中,并且預期測試將在這里結束。我們將按照建議進行操作并將 ?
?}?
?更改為??]?
?,使該行變?yōu)?/span>??if [ -d ./linuxmi ]; than?
?. 問題 4/8 已修復!我們重新運行 shellcheck,現在顯示以下內容:另一個單引號問題。我們已經知道如何解決這些問題。讓我們更改?
?echo 'sure! < start?
?為??echo 'sure!' < start?
?(問題 5/8 已修復?。┎⒃俅沃匦逻\行 shellcheck:有趣的是,我們看到 shellcheck 無法解析一行。雖然這看起來像是 shellcheck 中的一個缺點,但進一步閱讀,我們會發(fā)現?
?then?
?中的 ??e?
? 應該為 a。哦哦!我們要放置??than?
?而不是??then?
?. 多么粗心的錯誤?? 很容易修復(問題 6/8 已修復?。?。我們的腳本現在看起來像這樣:
echo 'Bash 不是 Hash'
echo "為我回應更多錯誤www.linuxmi.com"
if [ -d ./linuxmi ]; then
echo 'sure!' < start
fif
另一個 shellcheck 運行為我們提供了另一個有用的信息:我們把?
?fi?
?弄丟了!哦哦,是的,??fif?
?不行。我們要在腳本的最后一行更改??fif?
?為??fi?
?。(問題 7/8)修復。并再次運行 shellcheck!重定向問題。老實說,我沒想到?
?shellcheck?
?也會發(fā)現這個錯誤,因為??<?
?它也可以在 Bash 中使用,但它確實發(fā)現了。事實上,我們的重定向是為了??>?
?代替??<?
?.問題 8/8 - 所有問題 - 已修復!這就引出了最后一個腳本
echo 'Bash 不是 Hash'
echo "為我回應更多錯誤www.linuxmi.com"
if [ -d ./linuxmi ]; then
echo 'sure!' > start
fi
讓我們看看 shellcheck 現在是怎么想的。完美的!從第一次執(zhí)行開始,腳本運行完美。如果您查看各種 shellcheck 命令的輸出,您還會注意到 shellcheck 的另一個非常方便的功能。尤其是對于初學者:顯示一組超鏈接(網站鏈接),可以在終端窗口中單擊鼠標,或者您可以選擇(如有必要)> 右鍵單擊以復制然后粘貼到瀏覽器中。單擊此類鏈接將帶您進入shellcheck GitHub 項目。
想要快速檢查
如果您只想快速檢查最重要的選項,您可能希望查看該??--severity={SEVERITY}?
?選項,您可以將??{SEVERITY}?
?其中的一個替換為??error, warning, info, style?
?.因此,您只是在尋找錯誤和警告,您將使用??--severity=warning?
?(包括更高級別,在這種情況下僅為??error?
?)作為??shellcheck?
?的選項。
總結
如果腳本中的邏輯沒有問題,則??shellcheck?
?在執(zhí)行腳本之前運行并修復所有發(fā)現的問題將確保第一次運行時準完美。您甚至可以在該編碼挑戰(zhàn)中使用 shellcheck 進行下一次現場 Bash 編碼面試!在本文中,我們探討了腳本中可能出現的各種問題以及如何??shellcheck?
?處理它們。