當前位置:
首頁 > 科技 > 寫好shell腳本的13個技巧

寫好shell腳本的13個技巧

作者|Joseph Matthias Goh

譯者丨無明

編輯|張嬋 高效開發運維公眾號

產品的最終用戶通常不懂技術,所以不管你怎麼折騰產品代碼都無所謂。但腳本代碼不一樣,它們是開發人員寫給開發人員的。

有多少次,你運行./script.sh,然後輸出一些東西,但卻不知道它剛剛都做了些什麼。這是一種很糟糕的腳本用戶體驗。我將在這篇文章中介紹如何寫出具有良好開發者體驗的 shell 腳本。

產品的最終用戶通常不懂技術,所以不管你怎麼折騰產品代碼都無所謂。但腳本代碼不一樣,它們是開發人員寫給開發人員的。

這樣會導致一些問題:

混亂的腳本——我知道,我們都是工程師,讀得懂代碼,但即使這樣,也請為我們這些對 Shell 腳本不是很熟練的人考慮一下(我們在寫代碼時也會為你們考慮的)。

滿屏的日誌和錯誤輸出——就算我們也是工程師,並不代表我們了解你所做的一切。

弄得一團糟卻沒有做好清理工作——是的,我們可以順著你的腳本手動撤銷變更,但你真的會讓那些信任你的腳本的人這麼做嗎?

所以,我們可以通過一些方法來為自己和別人寫出更好的 shell 腳本。這裡給出的所有示例都可以使用與 POSIX 標準兼容的 shell 運行(#!/bin/sh),因為它是最常用的。嫌文章太長了可以只看以下總結部分:

提供標記

檢查所有命令的可用性

獨立於當前工作目錄

如何讀取輸入:環境變數 vs. 標記

列印對系統執行的所有操作

如果有必要,提供選項

重新開啟顯示

用動畫的方式顯示進度

用顏色編碼輸出

出現錯誤立即退出腳本

自己執行清理工作

在退出時使用不同的錯誤碼

在結束時列印一個新行

有時間的話可以接著往下看具體內容:

提供 --help 標記

安裝在系統上的二進位文件通常帶有幫助文檔,但對於腳本來說就不一定了。因此我們通常需要為腳本提供或標記來列印有關如何使用腳本的信息。如果其他工程師需要修改腳本,這也可以作為腳本的內聯文檔:

這段腳本先計算參數長度(),只有當參數長度不為零時才會檢查標記。下一個條件會檢查參數中是否存在字元串。第一個條件是必需的,如果參數長度為零則不需要列印幫助信息。

檢查所有命令的可用性

腳本通常會調用其他腳本或二進位文件。在調用可能不存在的命令時,請先檢查它們是否可用。可以使用「command -v 二進位文件名稱」來執行此操作,看看它的退出代碼是否為零。如果命令不可用,可以告訴用戶應該如何獲得這個二進位文件:

獨立於當前工作目錄

從不同的目錄執行腳本可能會發生錯誤,這樣的腳本沒有人會喜歡。要解決這個問題,請使用絕對路徑()和腳本的相對路徑(如下所示)。

可以使用引用腳本的當前路徑:

如何讀取輸入:環境變數 vs. 標記

腳本通過兩種方式接受輸入:環境變數和選項標記(參數)。根據經驗,對於不影響腳本行為的值,可以使用環境變數,而對於可能觸髮腳本不同流程的值,可以使用腳本參數。

不影響腳本行為的變數可能是訪問令牌和 ID 之類的東西:

影響腳本行為的變數可能是需要運行實例的數量、是非同步還是同步運行、是否在後台運行等參數:

列印對系統執行的所有操作

腳本通常會對系統執行有狀態的更改。不過,由於我們不知道用戶何時會向發送,也不知道腳本錯誤何時可能導致腳本意外終止,因此很有必要將正在做的事情列印在終端上,這樣用戶就可以在不去查看腳本的情況下回溯這些步驟:

在必要時提供 --silent 選項

有些腳本是為了將其輸出傳給其他腳本。雖說腳本都應該能夠單獨運行,不過有時候也有必要讓它們把輸出結果傳給另一個腳本。可以利用來實現標記:

重新開啟顯示

在使用關閉腳本顯示之後,如果發生致命錯誤,腳本將終止,而且不會恢復終端輸出,這樣對用戶來說是沒有意義的。可以使用來捕捉和其他操作系統級別的信號,然後使用打開終端顯示:

用動畫的方式顯示進度

有些命令需要運行很長時間,並非所有腳本都提供了進度條。在用戶等待非同步任務完成時,可以通過一些方式告訴他們腳本仍在運行。比如在循環中列印一些信息:

或者可以做一些更好玩的小玩意兒,比如:

http://mywiki.wooledge.org/BashFAQ/034。

用顏色編碼輸出

在腳本中調用其他二進位文件或腳本時,對它們的輸出進行顏色編碼,這樣就可以知道哪個輸出來自哪個腳本或二進位文件。這樣我們就不需要在滿屏的黑白輸出文本中查找想要的輸出結果。

理想情況下,腳本應該輸出白色(默認的,前台進程),子進程應該使用灰色(通常不需要,除非出現錯誤),使用綠色表示成功,紅色表示失敗,黃色表示警告。

可以使用,其中代表顏色代碼。有些腳本使用而不是,但要注意不適用於所有的 UNIX 系統。

正確示範

可在.sh 中使用的所有顏色和修飾符:

https://misc.flogisoft.com/bash/tip_colors_and_formatting。

出現錯誤立即退出腳本

表示從當前位置開始,如果出現任何錯誤都將觸發。相反,表示不管出現任何錯誤繼續執行腳本。

如果腳本是有狀態的(每個後續步驟都依賴前一個步驟),那麼請使用,在腳本出現錯誤時立即退出腳本。如果要求所有命令都要執行完(很少會這樣),那麼就使用。

自己執行清理工作

大多數腳本在出現錯誤時不會執行清理工作,能夠做好這方面工作的腳本實屬罕見,但這樣做其實很有用,還可以省下不少時間。前面已經給出過示例,讓恢復正常,並藉助命令來執行清理工作:

在退出時使用不同的錯誤碼

在絕大多數 shell 腳本中,exit 0 表示執行成功,exit 1 表示發生錯誤。對錯誤與錯誤碼進行一對一的映射,這樣有助於腳本調試。

這樣做有另一個額外的好處,就是其他腳本在調用你的腳本時,可以根據錯誤碼來判斷發生了什麼錯誤。

在結束時列印一個新行

如果你有在遵循腳本的最佳實踐,那麼可能會使用代替(它在不同系統中的行為有所差別)。問題是在命令結束後不會自動添加一個新行,導致控制台看起來是這樣的:

看起來是多麼的平淡

這樣一點也不酷,可以通過簡單的方式列印一個新行:

這樣就可以得到:

好多了哈

別人會感謝你這麼做的。

總 結

這篇文章大致總結了一些簡單易用的技巧,讓 shell 腳本更易於調試和使用。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 InfoQ 的精彩文章:

微軟收購Github,開發者到底在慌什麼?丨Q言Q語
引擎V8推出「並發標記」,可節省60%-70%的GC時間

TAG:InfoQ |