使用這些編碼技巧編寫快速、可讀的 Shell 腳本。
#Bash 無疑已經成為每個現代類 Unix 系統或基於 Unix 的作業系統的本地內建自動化解決方案。程式設計師使用 Bash 建立 Shell 腳本來自動化重複的命令列任務。 Bash 的主要目標是提供一個最小的語法來執行其他程式並處理它們的退出代和輸出。但是,現代的 Bash 解釋器具有完整的命令語言,提供大多數通用程式語言的功能。因此,我們可以透過包含傳統的命令列呼叫和演算法程式碼來編寫高度可讀的Shell腳本。現代的Bash版本引入了關聯數組和支援按引用傳遞的效能相關特性,使 Bash 具有與其他準備好進行 Shell 腳本編寫的語言競爭的能力。
在本文中,我將介紹一些 Bash 編碼技巧,您可以在您的 Shell 腳本中包含它們,使它們現代化、快速且可讀。使用這些技巧,您可以使用 Bash 編寫通用程式設計或演算法實現,例如演算法原型、實作實用程序,甚至是競賽程式設計!
傳統的 Bash 變數通常沒有類型,但您可以根據特定的處理上下文將其處理為整數、小數或字串。我們通常使用Bash變數來儲存命令輸出、演算法參數和其他臨時值。 Bash也支援兩種陣列類型:一維(以數字索引)和關聯(鍵值結構)。與其他流行的動態類型通用語言(例如Python、PHP 或 JavaScript)一樣,使用 Bash 陣列非常容易。以下是如何在 Bash 中建立陣列的方法:
#!/bin/bash #Linux迷 www.linuxmi.com numbers=(9 3 1 3 9) declare -a words words[0]='Linux迷' words[1]='LinuxMi' echo ${numbers[@]} ${words[@]}
以上程式碼輸出的陣列內容如下:
您可以透過 declare 內建指令檢查每個陣列引用的聲明,如下所示:
在 Bash 中檢查數組聲明,作者的螢幕截圖 您還可以使用最小的語法進行數組操作和處理活動,例如追加新項目、刪除現有項目、處理數組元素、排序等。例如,以下程式碼刪除無效的分數值並列印前三個最高分數:
#!/bin/bash #Linux迷 www.linuxmi.com declare -a marks marks+=(75 65 80 102 26) # class A marks marks+=(103 68) # class B marks # 删除无效标记 for i in "${!marks[@]}"; do if ((marks[i] > 100)); then unset "marks[$i]" fi done # 对所有标记进行排序 marks_s=($(printf '%s\n' "${marks[@]}" | sort -nr)) # 打印前 3 名 echo ${marks_s[0]} ${marks_s[1]} ${marks_s[2]}
以上程式碼會產生一個單獨的進程進行排序,因為我們使用了 sort 外部命令,但是您可以透過使用一些 Bash 程式碼實現簡單的排序演算法,例如選擇排序,來避免這種情況。
#在一些程式設計場景中,我們需要在 shell 腳本中儲存鍵值對資料。程式設計師通常使用鍵值資料結構來建立字典結構、映射和快取容器(透過記憶化)。如果您使用 Python 編寫您的 shell 腳本,您可以使用內建的字典資料結構來儲存鍵值資料。如何在 Bash 中使用字典結構?
Bash 4.0 版本引入了關聯數組功能,用於儲存鍵值資料。下面是一個 Bash 關聯數組的簡單範例:
#!/bin/bash #Linux迷 www.linuxmi.com declare -A marks=([linux]=39 [ubuntu]=27 [debian]=83 [fedora]=59) for key in "${!marks[@]}"; do printf "$key \t ${marks[$key]} \n" done
在這裡,我們使用了 !mapvar[@] 語法來提取所有字典鍵作為數組進行迭代。上述程式碼將列印所有鍵和對應的值,如下所示:
Bash 讓你可以使用最少的語法來操作和存取關聯陣列資料。使用Bash關聯數組的方式就像使用 Python 字典一樣。請看下面的範例:
#!/bin/bash #Linux迷 www.linuxmi.com read -p "Enter coords (i.e., [x]=10 [y]=12): " coords declare -A "coords=($coords)" if [ ! -v "coords[x]" ]; then coords[x]=5 fi if [ ! -v "coords[y]" ]; then coords[y]=10 fi for key in "${!coords[@]}"; do printf "$key = ${coords[$key]} \n" done
以上原始程式碼向使用者要求x和y座標,為缺少的座標軸值設定預設值,並在終端上列印它們。在這裡,我們使用! -v語法,因為通常我們使用 Python 字典中的 not in。
当您通过 Bash 解释器执行 shell 脚本时,操作系统会创建一个新的 Bash 进程,并将您的脚本文件作为第一个命令行参数。操作系统通常允许您将一系列参数传递给每个操作系统进程。当您为其他命令/进程提供命令行参数时,您也可以将它们传递到您的 Bash 脚本中。假设您需要将两个整数值传递给脚本。然后,您可以轻松使用 和2 分别访问第一个和第二个参数值。但是,当您使用更多索引参数并且需要实现可选参数(也称为命令行标志或选项)时,事情将变得复杂。
作为这种情况的解决方案,您可以使用内置的 getopts 来使用命名参数。使用以下 shell 脚本,我们可以覆盖一些脚本中的默认值:
#!/bin/bash #Linux迷 www.linuxmi.com title="Linux迷 www.linuxmi.com" message="Hello world!www.linuxmi.com Linux迷" while getopts ":t:m:" option; do echo $option case "${option}" in t) title=${OPTARG} ;; m) message=${OPTARG} ;; esac done zenity --info --title="$title" --text="$message"
默认情况下,上面的脚本显示一个带有默认标题和消息的 GTK 消息框,但是您可以使用命名的命令行参数来覆盖它们,如下所示:
./linuxmi.com.sh -t "hello" ./linuxmi.com.sh -m "world"
getopts 内置支持仅使用单个字母选项。您可以使用 getopt 来使用长形式选项(即–title),如此 gist 所示。
引用传递是一种编程语言特性,它允许您通过内存引用将数据传递到函数中,而不是将整个数据段复制到新变量中。C ++ 程序员总是努力编写性能优先的代码,对于类对象,结构体和字符串,使用引用传递而不是值传递。
如果您使用的是 Bash 4.3 或更新版本,则可以使用名称引用在 shell 脚本中实现引用传递。以下是一个简单的示例代码片段,通过函数更改字符串变量:
#!/bin/bash #Linux迷 www.linuxmi.com function change_str_var() { local str_new="Bash" local -n str_ref=$1 echo "$str_ref -> $str_new" # Python -> Bash str_ref=$str_new } str="Python" change_str_var str echo $str # Bash
上述 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 还允许您为变量添加一些修饰符属性。例如,您可以创建仅包含小写字母或大写字母的字符串,如下所示:
declare -l lc_str="Hello World" declare -u uc_str uc_str="Hello" uc_str="World" echo $lc_str # hello world echo $uc_str # WORLD
使用 Bash 变量属性,您可以编写更少出错、更易读、更现代的 shell 脚本。
相关:Bash 特殊变量(,?,#,@,$$,$*) 见 https://www.linuxmi.com/bash-special-variables.html
如果还有什么疑问与建议,请在评论栏里给我们留言。感谢您的阅读。
以上是一文了解什麼是 Linux 上的套件依賴的詳細內容。更多資訊請關注PHP中文網其他相關文章!