0.索引
- 大多數人發生的事情
- 腳本的結構
- 在屏幕上打印
- 讀取用戶輸入
- bash中的計算
- 條款
- 循環
- 功能
- 蓋普特斯
1.大多數人發生的事情
/ bin / bash或/ bin / sh
當執行我們的腳本時,機器要做的第一件事就是查看應該使用哪個shell。 在大多數最新的Linux系統上 / bin / sh的 是一個鏈接 / bin / bash,但並非總是如此,例如在使用 busybox的 他們帶來了 Sh 通常他們也帶來 巴什,但如果您使用 / bin / sh的,它將無法與Bash一起運行。 這就是為什麼我建議始終使用 / bin / bash.
Unicode與ASCII
您是否曾經想過為什麼不能在腳本中使用“¿”或“?”? 還是使用口音? 在交互式腳本中可能會很煩人。 那是因為Bash的默認編碼是ASCII,或者說是相同的英文字符集。 要更改它,我們只需要告訴腳本我們要使用Unicode。 為此,您必須在命令解釋器之後添加一行:
#-*-編碼:UTF-8-*-
請注意,這一行在腳本的開頭很重要。
使腳本可執行
有趣的是,有多少人使用«$ bash腳本.sh“ 代替 ”$ ./腳本.sh畢竟,這就是我們定義的外殼程序。
要添加執行權限,您必須執行:
須藤+ x script.sh
BIN =“我們有腳本的文件夾” PATH =“ $ BIN $ PATH”
2.腳本的結構
- Cabecera
- 全局變量的定義
- 幫助
- 功能
- 主體
標頭是我們指示要使用的shell和編碼的位置。 該功能的優點是可以重複使用僅編寫一次即可重複的代碼,並使腳本更易於理解,對於超過100行的代碼而言,這非常有用。
為了使用函數,必須在腳本主體之前使用定義它們。 而且,如果我們想在主體和函數中的所有腳本的全局級別使用變量,則必須在所有內容的開頭,標題之後定義它們。
最後,優良作法是在腳本運行錯誤或參數錯誤時編寫幫助函數。 顯然,在這些情況下,我們希望立即退出腳本,而不讀取函數。 為此,我們可以使用:
函數help(){echo“”“我們的格式正確的幫助文本。”“”如果[[-z $ 1 || $ 1 ==“ -h” || $ 1 ==“ --help”]]; 然後幫忙
如果在幫助功能中添加“退出”,則每次運行幫助時(例如,在出現錯誤消息後等),我們都會退出腳本。 我們保存了幾行代碼。
該條件表示在屏幕上顯示幫助,如果腳本沒有參數運行或指定了-h / –help,則退出。 如果您看一下,那是大多數Linux程序的標準行為。
3.在屏幕上打印
有2條用於以bash打印到屏幕的主要命令:«錯過»ÿ«的printf«。 它們既快又都是bash的一部分。 初學者的主要區別是echo在末尾添加了換行符,而«的printf“才不是。
迴聲非常好,並且是大多數人使用的迴聲,但是,當讀取用戶的INPUT時,或者當您希望通過字處理打印從文件中獲取的變量時,可能會發生奇怪的事情。 它們通常很容易解決,就像將雙引號更改為單引號或反之亦然,或從引號中刪除變量引用一樣容易。 «Echo»根據我們的編譯方式,是否還會發生奇怪的事情,如果我們始終使用Ubuntu或Fedora,它不會影響我們,但是如果更改發行版,它會影響我們。
這就是為什麼我使用«的printf«,這不會讓我頭疼,而且表現得更像«的printf»從C或«打印»對於Python,如果您想將腳本移植到另一種編程語言,那麼這非常重要。
4.讀取用戶INPUT
我們在腳本名稱之後和按ENTER鍵之前編寫的所有內容都會自動保存在特殊變量中。 這些變量的類型為$ X,其中X是數字。
«$0»表示我們腳本的名稱,並來自«$1»無窮大,我們稍後編寫的所有內容都是可變的。 例如:
cat << EOF >> test.sh#!/ bin / bash#-*-編碼:UTF-8-*-printf“ \ $ 0 = $ 0 \ n” printf“ \ $ 1 = $ 1 \ n” printf “ \ $ 2 = $ 2 \ n” EOF chmod + x script.sh ./script.sh我的file.txt
我們創建一個測試腳本,使其可執行,並使用2個參數運行它。 我們獲得以下屏幕輸出:
$ 0 = ./script.sh $ 1 =我的$ 2 = file.txt
使用引號,我們可以將“ my file.txt”傳遞給“ $ 1”。
我們還可以使用“ read”命令讀取用戶的INPUT,直接指示要在其中保存參數的變量。 例如:
printf“你叫什麼名字?\ n”讀為NAME printf“你好,$ NAME。\ n”
5. Bash中的計算
為此,我們可以使用«表達式«,只要我們不需要進行複雜的計算即可。 應該注意兩件事,第一件事是«表達式»僅接受整數,其次是除法返回整個結果,以查看我們可以使用的其餘部分«%“。
通常,我們希望將expr的結果分配給變量。 我們可以通過兩種方式做到這一點:
VAR2 =`expr $ VAR1 / 10` VAR2 = $(expr $ VAR1 / 100)
您也可以跳過«表達式»使用雙括號:
VAR2 = $((($ VAR1 / 100))
6。 條款
關於“if“,”其他“,”ELIF»和條件。 您可以在以下內容中了解到:
我只想強調使用簡單方括號之間的區別,«[]«和雙括號,«[[]]«,關於條件。 使用雙括號,我們可以使用其他條件:
- «&&»和
- «||»對於或
使用“&&»ÿ«||»使用簡單的方括號,應將每個零件分開放在單獨的方括號中。 用於查看是否需要執行幫助的腳本部分的示例為:
如果 [ -z "$1" ] || [“$1”==“-h”] || [“$1”==“--help”]]; 然後幫助fi
這也使我們不必為了避免錯誤而在引號中寫變量名。 例如:
如果[$ 1 = 1]; 然後printf“參數等於1。”; fi如果[“ $ 1” = 1]; 然後printf“參數等於1。”; fi如果[[$ 1 = 1]]; 然後printf“參數等於1。”; 科幻
如果在沒有任何參數的情況下運行script.sh,則第一種情況將產生錯誤:
bash:[:=:期望一元運算符
尚未談論的是«手機殼«,用於簡化«if«。 讓我們從頭開始,當我們沒有任何«if»所有代碼將被執行。 如果我們添加條件«if»我們將有兩種情況,一種是“if»以及另一種不執行此塊的情況。
如果我們添加«其他«我們還將有兩種情況,但這兩種情況與以前的情況有所不同。 因為現在將有兩個條件代碼塊,A和B,以及C塊,這是程序的其餘部分。 A或B將被執行,而C將被執行。在先前的情況下,它是A和C或僅是C。
為避免書寫條件«如果別的“ 內 ”其他»為簡化代碼的讀取,它是創建的«ELIF«。 當我們有許多條件取決於上一個條件時,例如數字範圍或類型:
如果[[$ VAR1 = 1]],則VAR1 = $ 1; 然後printf“ 1 \ n” elif [[$ VAR1 = 2]]; 然後printf“ 2 \ n” elif [[$ VAR1 = 3]]; 然後printf“ 3 \ n” else printf“ none \ n” fi
對於最後一個«ELIF»將閱讀許多條件。 在這種情況下,簡化了該過程:
VAR1 = $ 1 case $ VAR in 1)printf“ 1 \ n” ;; 2)printf“ 2 \ n” ;; 3 | 4)printf“ 3或4,取決於\ n” ;; *)printf“ none \ n” ;; 那C
將讀取一個變量,在這種情況下為VAR1,將看到它是否等同於任何情況,否則將執行默認情況“ *”。 雙分號等效於«打破“, 他們告訴”手機殼»那必須結束。
7.循環
在任何編程語言中,很少有循環是已知的。 在Bash中,它們是«而“,”直到»ÿ«對於«。 關於這些的內容已經寫在博客中:
循環有兩種類型«對於«,屬於那種«$用於LOQUESEA中的VAR»以及C類型是什麼«$ for((我= 0;我<= 10;我++))«。 第二種循環«對於»非常有用,它在循環開始時包含3個部分:
- 變量的聲明和初始化(在這種情況下為輔助變量“ I = 0”)。
- 執行條件(直到I小於或等於10)。
- 輔助變量的增加
我認為這是所有循環中最強大的循環。 一個示例,顯示從0到10的所有數字,包括:
#!/ bin / bash for((I = 0; I <= 10; I ++)); 做printf“ $ I \ n”完成
8.功能
Bash不允許我們做某些事情,對吧? 乍一看,bash函數阻止您執行三件事:在函數中聲明局部變量,將參數傳遞給函數以及返回參數。 一切都有解決方案。
什麼都不做:
#!/ bin / bash VAR = 1 printc“ $ VAR \ n”函數hello(){VAR = 2 printf“ $ VAR \ n”}你好printf“ $ VAR \ n”
打印到屏幕1、2和2。
要聲明局部變量,請添加«當地»聲明時:
#!/ bin / bash VAR = 1 printf“ $ VAR1 \ n”函數foo(){本地VAR1 = 2 printf“ $ VAR1 \ n”} printf“ $ VAR1 \ n” foo printf“ $ VAR1 \ n”
在屏幕上打印1、1、2、1。
如何將參數傳遞給函數?
#!/ bin / bash#-*-編碼:UTF-8-*-function hello(){printf“ Hello $ 1 \ n”}
printf“你叫什麼名字?\ n”
讀取VAR1
你好$ VAR1
如何返回參數?
#!/ bin / bash#-*-編碼:UTF-8-*-function hello(){printf“ Hello holita”} printf“您叫什麼名字?\ n”讀取VAR1 VAR1 = $(hello)#在這裡printf“ $ VAR1 $ VAR2 \ n”
如您所見,這有兩個缺點,您只能返回一個參數,該參數可以是向量😀,並且如果要返回參數,則無法再從該函數在屏幕上打印。
9.Getops
您需要了解有關Bash創建複雜腳本的最後一件事是«傻瓜«。 它用於將選項傳遞給腳本,而不考慮順序。 唯一的缺點是它只會影響空頭期權:
#!/ bin / bash#-*-編碼:UTF-8-*-VARC = 0 function help(){printf“幫助消息\ n”退出},如果[[-z $ 1]]; 然後在getopts時幫助fi:ha:b:c OPT; 在h)幫助中做$ OPT的情況;; :) 救命 ;; a)VARA = $ OPTARG ;; b)VARB = $ OPTARG ;; c)VARC = 1 ;; \?) 救命 ;; esac done#使用VARA,VARB和VARC進行處理的腳本的主要塊
«獲取選項»逐個讀取選項,因此需要循環。
可以使用«傳遞兩種類型的選項獲取選項“:
- 參數稱為標誌,在這種情況下為-c或-h。 它們用我們要使用的字母指定。 它們就像布爾變量,«真»(是)或«假”(他們不在這裡)。
- 帶有關聯參數的參數-a任何東西-b任何東西。 它們用我們想要的字母指定,下面用冒號表示。 參數存儲在OPTARG中(此名稱不可更改)。
這個腳本做什麼?
在不傳遞任何選項,傳遞“ -h”參數,傳遞無效參數(例如,“-x”,由“ \?”完成)時顯示幫助消息。參數(“:”)。 在其餘情況下,它將VARC中存在的“ -c”保存為1,並且在VARA和VARB中將值分別用“ -a”和“ -b”傳遞。
很好我不再說U_U
您好,很好的文章。
嘿,您授予sudo + x而不是chmod + x權限
$ sudo chmod + x script.sh
(更確切地說,呵呵)
啊,恭喜你,謝謝!
很好的帖子,我真的很祝賀你,請繼續保持,問候
而且,如果您希望腳本在執行時可見,請逐步查看例如變量,條件和所有內容的行為,則可以使用:
sh -x腳本
問候
護身符。 很好,很好解釋。
謝謝。
關於這個主題的優秀文章
非常有趣,非常重要,感謝您提供的信息…。
乾杯!
謝謝大家的祝賀,對於Miguel命令,一旦發布該條目,他將不允許我進行修改。 我想這將必須做得很好。
很好!
首先,我想向您表示祝賀,我發現它很容易理解,並且確實有助於遵循指南以進行bash編程,特別是對於開始編程的人。
但是,我發現了一些細節,我認為應該更正。
首先:在第2節中。 腳本的結構»該函數未關閉,在腳本中執行該函數時會導致問題。
解決方案是在“ exit”命令之後添加一個括號。
第二:第«4節。 閱讀用戶輸入“您確認用戶可以輸入的參數的範圍是$ 0到無窮大,但是,” bash”只能解釋為$ 0到$ 9,因為$ 10等於$ 1 + 0。
要解決此問題,您可以使用“ shift”命令獲取以下變量。 或者在大括號“ $ {10}”中指定變量,以便bash將值合計,而不是$ 1 + 0。
事不宜遲,問候!
謝謝你的評論。 在腳本和函數中完全無法解釋退出的正確用法。 至於$ {10},我從來沒有遺贈過這麼多東西,所以我還沒有遇到這個問題,很高興知道有解決方案(我已經淘汰了今天學到的新知識😀)。
非常感謝您的文章! 您提到的某些事情仍然缺乏澄清。 例如,getops。
在屏幕輸出部分,您沒有提及您稍後提到的貓...
貓<
***************************************
*此表格非常具有表達力*
***************************************
EOF
在您的示例中:
貓《 EOF》 test.sh
必須提到兩件事……>>是“追加”,也就是說,如果重複相同的命令,則整個腳本將重複一遍……您只能使用一個……
貓<< EOF> script.sh
是的,它也應該稱為script.sh
然後在
如果[-z“ $ 1”] || [“ $ 1” ==“ -h”] || [“ $ 1” ==“ -help”]]]; 然後
幫助
fi
我認為應該寫...
如果[[-z“ $ 1”] || [“ $ 1” ==“ -h”] || [“ $ 1” ==“ -help”]]]; 然後
...
BASH還有更多發現。
您可以將其命名為“基本”嗎? 🙂
例如,參數'testers'類似於-z來查看它們是否為空,或者像-f一樣來查看它是否作為文件存在。
再次感謝您的努力。
阿爾貝托
一個非常好的bash腳本教程!
- -編碼:UTF-8- -
這是我第一次看到該行在bash腳本中設置字符編碼。 Python似乎比Bash更典型。 真的有必要嗎? 我已經在Google上搜索了參考文獻,但找不到任何東西,您手上是否有談論此事的鏈接? 特別是關於那條線的適用性。
我認為,要使用UTF-8在Bash中編寫腳本,只需保存文本文件(不包含BOM),並正確設置某些環境變量(LANG和LC_ *)。
然後,顯然,必須為ASCII以外的其他編碼準備執行的命令。 例如,如果我們要大寫,這似乎不起作用:
«Echoáéíóú| 特拉茲(AZ)»
o:
«Echoáéíóú| tr [:較低:] [:較高:]»
最好使用:
«Echoáéíóú| awk'{print toupper($ 0)}'»。
有關 ”編碼»之前在此博客中已提及:
Bash:如何使腳本可執行
安裝後實用程序腳本
有人糾正了我,但該編碼行(#--編碼:UTF-8--)與bash或shell無關:它是註釋行(以#開頭),用於告訴EDITOR我們用來編寫腳本(vim,emacs ...)的文件編碼。
實際上,bash看不到這樣的行,因為它是註釋行。
出色的教程,因為Sysadmin知道Bash中的腳本是必不可少的,它對所有內容都非常有用。
非常非常好!
的問候!
如果這對任何人都有用,則可以使用以下幾種用法和示例來創建自己的腳本: https://github.com/reduardo7/hsabx
挺好。 新內容添加到我的腳本中。 encodig和printf東西沒有它。
謝謝!!!
太好了! 我將其保留為收藏夾,它可以糾正錯誤,甚至提供更多內容來擴展。 為所有這些信息鼓掌!