每個程序員都應知道的五個 Bash 編碼技巧
Bash 無疑已經成為每個現代類 Unix 系統或基于 Unix 的操作系統的本地內置自動化解決方案。程序員使用 Bash 創建 Shell 腳本來自動化重復的命令行任務。Bash 的主要目標是提供一種最小的語法來執行其他程序并處理它們的退出代碼和輸出。但是,現代的 Bash 解釋器具有完整的命令語言,提供大多數通用編程語言的功能。因此,我們可以通過包含傳統的命令行調用和算法代碼編寫高度可讀的Shell腳本?,F代的Bash版本引入了關聯數組和支持按引用傳遞的性能相關特性,使 Bash 具有與其他準備好進行 Shell 腳本編寫的語言競爭的能力。
在本文中,我將介紹一些 Bash 編碼技巧,您可以在您的 Shell 腳本中包含它們,使它們現代化、快速和可讀。使用這些技巧,您可以使用 Bash 編寫通用編程或算法實現,例如算法原型、實現實用程序,甚至是競爭編程!
在 Shell 腳本中使用數組
傳統的 Bash 變量通常沒有類型,但是您可以根據特定的處理上下文將其處理為整數、小數或字符串。我們通常使用Bash變量來存儲命令輸出、算法參數和其他臨時值。Bash還支持兩種數組類型:一維(按數字索引)和關聯(鍵值結構)。與其他流行的動態類型通用語言(例如Python、PHP 或 JavaScript)一樣,使用 Bash 數組非常容易。以下是如何在 Bash 中創建數組的方法:
以上代碼輸出的數組內容如下:
您可以通過 declare 內置命令檢查每個數組引用的聲明,如下所示:
在 Bash 中檢查數組聲明,作者的屏幕截圖 您還可以使用最小的語法進行數組操作和處理活動,例如追加新項、刪除現有項、處理數組元素、排序等。例如,以下代碼刪除無效的分數值并打印前三個最高分數:
以上代碼會生成一個單獨的進程進行排序,因為我們使用了 sort 外部命令,但是您可以通過使用一些 Bash 代碼實現簡單的排序算法,例如選擇排序,來避免這種情況。
創建映射或字典
在一些編程場景中,我們需要在 shell 腳本中存儲鍵值對數據。程序員通常使用鍵值數據結構來創建字典結構、映射和緩存容器(通過記憶化)。如果您使用 Python 編寫您的 shell 腳本,您可以使用內置的字典數據結構來存儲鍵值數據。如何在 Bash 中使用字典結構?
Bash 4.0 版本引入了關聯數組功能,用于存儲鍵值數據。下面是一個 Bash 關聯數組的簡單示例:
在這里,我們使用了 !mapvar[@] 語法來提取所有字典鍵作為數組進行迭代。上述代碼將打印出所有鍵和對應的值,如下所示:
Bash 讓你可以使用最少的語法來操作和訪問關聯數組數據。使用Bash關聯數組的方式就像使用 Python 字典一樣。請看下面的例子:
以上源代碼向用戶請求x和y坐標,為缺失的坐標軸值設置默認值,并在終端上打印它們。在這里,我們使用! -v語法,因為通常我們使用 Python 字典中的 not in。
實現命名參數支持
當您通過 Bash 解釋器執行 shell 腳本時,操作系統會創建一個新的 Bash 進程,并將您的腳本文件作為第一個命令行參數。操作系統通常允許您將一系列參數傳遞給每個操作系統進程。當您為其他命令/進程提供命令行參數時,您也可以將它們傳遞到您的 Bash 腳本中。假設您需要將兩個整數值傳遞給腳本。然后,您可以輕松使用 $1 和 $2 分別訪問第一個和第二個參數值。但是,當您使用更多索引參數并且需要實現可選參數(也稱為命令行標志或選項)時,事情將變得復雜。
作為這種情況的解決方案,您可以使用內置的 getopts 來使用命名參數。使用以下 shell 腳本,我們可以覆蓋一些腳本中的默認值:
默認情況下,上面的腳本顯示一個帶有默認標題和消息的 GTK 消息框,但是您可以使用命名的命令行參數來覆蓋它們,如下所示:
getopts 內置支持僅使用單個字母選項。您可以使用 getopt 來使用長形式選項(即–title),如此 gist 所示。
使用函數中的引用傳遞
引用傳遞是一種編程語言特性,它允許您通過內存引用將數據傳遞到函數中,而不是將整個數據段復制到新變量中。C ++ 程序員總是努力編寫性能優先的代碼,對于類對象,結構體和字符串,使用引用傳遞而不是值傳遞。
如果您使用的是 Bash 4.3 或更新版本,則可以使用名稱引用在 shell 腳本中實現引用傳遞。以下是一個簡單的示例代碼片段,通過函數更改字符串變量:
上述 change_str_var 函數使用 local 命令創建一個局部的 str_ref 引用,引用全局的 str 變量。然后,它通過覆蓋舊字符串值來分配一個新的字符串值。
一些程序員在函數內部使用 echo 命令,并通過命令替換特性調用特定函數以從 Bash 函數返回值(因為原生 Bash return 關鍵字僅支持返回有效的退出代碼)。這會生成另一個子 shell 并消耗更多資源。因此,現在程序員可以使用引用傳遞并編寫性能優先的Bash函數返回,如果他們使用新的 Bash 版本。
使用類型和修飾符屬性的變量
Bash 被稱為一種無類型命令語言。換句話說,它通常將變量數據處理為字符串,但根據上下文(例如在算術擴展中)進行相應處理。另一方面,Bash 也允許程序員使用類型屬性,并提供兩種內置的數組類型。即使有了這些功能,我們也不能將 Bash 視為純動態類型語言,但這些變量屬性將Bash置于無類型和動態類型語言之間。
Bash 支持使用整數變量屬性將特定變量標記為整數。一旦創建了一個整數變量,當您分配非整數值時,Bash 會發出警告,如下所示:
Bash 還允許使用 declare -r 命令創建常量。每當您的腳本嘗試更改常量時,Bash 會在屏幕上打印錯誤消息。此外,正如我們之前使用的那樣,您可以使用 declare 內置函數創建數組。
Bash 還允許您為變量添加一些修飾符屬性。例如,您可以創建僅包含小寫字母或大寫字母的字符串,如下所示:
使用 Bash 變量屬性,您可以編寫更少出錯、更易讀、更現代的 shell 腳本。