重擊理論

/ bin / bash

0.索引

  1. 大多數人發生的事情
  2. 腳本的結構
  3. 在屏幕上打印
  4. 讀取用戶輸入
  5. bash中的計算
  6. 條款
  7. 循環
  8. 功能
  9. 蓋普特斯

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
如果腳本是可執行的,則可以將其添加到PATH中,並使其可以從計算機上的任何位置/文件夾執行。 為此,我們必須將其添加到用戶的.bashrc或/ etc / bashrc行中
BIN =“我們有腳本的文件夾” PATH =“ $ BIN $ PATH”
變量名全部大寫是 Bash 的策略。 許多人不遵循這條規則,但對於長腳本來說,它是值得讚賞的,因為它們使它們更具可讀性。

2.腳本的結構

  1. Cabecera
  2. 全局變量的定義
  3. 幫助
  4. 功能
  5. 主體

標頭是我們指示要使用的shell和編碼的位置。 該功能的優點是可以重複使用僅編寫一次即可重複的代碼,並使腳本更易於理解,對於超過100行的代碼而言,這非常有用。

為了使用函數,必須在腳本主體之前使用定義它們。 而且,如果我們想在主體和函數中的所有腳本的全局級別使用變量,則必須在所有內容的開頭,標題之後定義它們。

最後,優良作法是在腳本運行錯誤或參數錯誤時編寫幫助函數。 顯然,在這些情況下,我們希望立即退出腳本,而不讀取函數。 為此,我們可以使用:

函數help(){echo“”“我們的格式正確的幫助文本。”“”如果[[-z $ 1 || $ 1 ==“ -h” || $ 1 ==“ --help”]]; 然後幫忙

如果在幫助功能中添加“退出”,則每次運行幫助時(例如,在出現錯誤消息後等),我們都會退出腳本。 我們保存了幾行代碼。

該條件表示在屏幕上顯示幫助,如果腳本沒有參數運行或指定了-h / –help,則退出。 如果您看一下,那是大多數Linux程序的標準行為。

將3引號與echo一起使用可以使用換行符,而不會使消息顯示為echo。 對於多行消息,只使用一次迴聲更為方便。

3.在屏幕上打印

有2條用於以bash打印到屏幕的主要命令:«錯過»ÿ«的printf«。 它們既快又都是bash的一部分。 初學者的主要區別是echo在末尾添加了換行符,而«的printf“才不是。

迴聲非常好,並且是大多數人使用的迴聲,但是,當讀取用戶的INPUT時,或者當您希望通過字處理打印從文件中獲取的變量時,可能會發生奇怪的事情。 它們通常很容易解決,就像將雙引號更改為單引號或反之亦然,或從引號中刪除變量引用一樣容易。 «Echo»根據我們的編譯方式,是否還會發生奇怪的事情,如果我們始終使用Ubuntu或Fedora,它不會影響我們,但是如果更改發行版,它會影響我們。

這就是為什麼我使用«的printf«,這不會讓我頭疼,而且表現得更像«的printf»從C或«打印»對於Python,如果您想將腳本移植到另一種編程語言,那麼這非常重要。

有關更廣泛的討論,您可以訪問 來自Stack Exchange上Unix和Linux的這個問題.

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”
注意變量的分配。 “ $ VAR = content”將產生錯誤,等號,變量名稱和內容之間不能留空格。 正確的用法是“ VAR =內容”

5. Bash中的計算

為此,我們可以使用«表達式«,只要我們不需要進行複雜的計算即可。 應該注意兩件事,第一件事是«表達式»僅接受整數,其次是除法返回整個結果,以查看我們可以使用的其餘部分«%“。

通常,我們希望將expr的結果分配給變量。 我們可以通過兩種方式做到這一點:

VAR2 =`expr $ VAR1 / 10` VAR2 = $(expr $ VAR1 / 100)

您也可以跳過«表達式»使用雙括號:

VAR2 = $((($ VAR1 / 100))
要進一步了解«表達式»或者使用整數的替代方法,您可以看一下 這KZKG ^ gaara條目.

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:[:=:期望一元運算符
在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,將看到它是否等同於任何情況,否則將執行默認情況“ *”。 雙分號等效於«打破“, 他們告訴”手機殼»那必須結束。

«Case 外殻»也可以用作序列的«if«,為此您必須使用«;;&»(繼續)代替«;;» (停)。

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”

如您所見,這有兩個缺點,您只能返回一個參數,該參數可以是向量😀,並且如果要返回參數,則無法再從該函數在屏幕上打印。

您可以在 [url=https://blog.desdelinux.net/programando-en-bash-parte-3/]這篇文章來自 Usemoslinux[/url]。

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”傳遞。


發表您的評論

您的電子郵件地址將不會被發表。 必填字段標有 *

*

*

  1. 負責數據:MiguelÁngelGatón
  2. 數據用途:控制垃圾郵件,註釋管理。
  3. 合法性:您的同意
  4. 數據通訊:除非有法律義務,否則不會將數據傳達給第三方。
  5. 數據存儲:Occentus Networks(EU)託管的數據庫
  6. 權利:您可以隨時限制,恢復和刪除您的信息。

  1.   拉夫 他說:

    很好我不再說U_U

  2.   米格爾 他說:

    您好,很好的文章。
    嘿,您授予sudo + x而不是chmod + x權限

    1.    亨利 他說:

      $ sudo chmod + x script.sh
      (更確切地說,呵呵)

      啊,恭喜你,謝謝!

  3.   火冷 他說:

    很好的帖子,我真的很祝賀你,請繼續保持,問候

  4.   古斯塔沃 他說:

    而且,如果您希望腳本在執行時可見,請逐步查看例如變量,條件和所有內容的行為,則可以使用:

    sh -x腳本

    問候

  5.   達戈 他說:

    護身符。 很好,很好解釋。
    謝謝。

  6.   加布里埃爾 他說:

    關於這個主題的優秀文章

  7.   馬里奧·吉列爾莫·扎瓦拉·席爾瓦 他說:

    非常有趣,非常重要,感謝您提供的信息…。
    乾杯!

  8.   不來自布魯克林 他說:

    謝謝大家的祝賀,對於Miguel命令,一旦發布該條目,他將不允許我進行修改。 我想這將必須做得很好。

  9.   阿德里安 他說:

    很好!

    首先,我想向您表示祝賀,我發現它很容易理解,並且確實有助於遵循指南以進行bash編程,特別是對於開始編程的人。

    但是,我發現了一些細節,我認為應該更正。

    首先:在第2節中。 腳本的結構»該函數未關閉,在腳本中執行該函數時會導致問題。
    解決方案是在“ exit”命令之後添加一個括號。

    第二:第«4節。 閱讀用戶輸入“您確認用戶可以輸入的參數的範圍是$ 0到無窮大,但是,” bash”只能解釋為$ 0到$ 9,因為$ 10等於$ 1 + 0。
    要解決此問題,您可以使用“ shift”命令獲取以下變量。 或者在大括號“ $ {10}”中指定變量,以便bash將值合計,而不是$ 1 + 0。

    事不宜遲,問候!

    1.    不來自布魯克林 他說:

      謝謝你的評論。 在腳本和函數中完全無法解釋退出的正確用法。 至於$ {10},我從來沒有遺贈過這麼多東西,所以我還沒有遇到這個問題,很高興知道有解決方案(我已經淘汰了今天學到的新知識😀)。

  10.   io 他說:

    非常感謝您的文章! 您提到的某些事情仍然缺乏澄清。 例如,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一樣來查看它是否作為文件存在。

    再次感謝您的努力。
    阿爾貝托

  11.   小丑 他說:

    一個非常好的bash腳本教程!

  12.   OCZ 他說:

    - -編碼:UTF-8- -

    這是我第一次看到該行在bash腳本中設置字符編碼。 Python似乎比Bash更典型。 真的有必要嗎? 我已經在Google上搜索了參考文獻,但找不到任何東西,您手上是否有談論此事的鏈接? 特別是關於那條線的適用性。

    我認為,要使用UTF-8在Bash中編寫腳本,只需保存文本文件(不包含BOM),並正確設置某些環境變量(LANG和LC_ *)。
    然後,顯然,必須為ASCII以外的其他編碼準備執行的命令。 例如,如果我們要大寫,這似乎不起作用:
    «Echoáéíóú| 特拉茲(AZ)»
    o:
    «Echoáéíóú| tr [:較低:] [:較高:]»
    最好使用:
    «Echoáéíóú| awk'{print toupper($ 0)}'»。

    1.    不來自布魯克林 他說:

      有關 ”編碼»之前在此博客中已提及:

      Bash:如何使腳本可執行
      安裝後實用程序腳本

    2.    像你這樣的borriquito 他說:

      有人糾正了我,但該編碼行(#--編碼:UTF-8--)與bash或shell無關:它是註釋行(以#開頭),用於告訴EDITOR我們用來編寫腳本(vim,emacs ...)的文件編碼。

      實際上,bash看不到這樣的行,因為它是註釋行。

  13.   1987年JoRgE 他說:

    出色的教程,因為Sysadmin知道Bash中的腳本是必不可少的,它對所有內容都非常有用。

    非常非常好!

    的問候!

  14.   愛德華多·庫莫(Eduardo Cuomo) 他說:

    如果這對任何人都有用,則可以使用以下幾種用法和示例來創建自己的腳本: https://github.com/reduardo7/hsabx

  15.   利托·布萊克 他說:

    挺好。 新內容添加到我的腳本中。 encodig和printf東西沒有它。
    謝謝!!!

  16.   xxxtonxxx 他說:

    太好了! 我將其保留為收藏夾,它可以糾正錯誤,甚至提供更多內容來擴展。 為所有這些信息鼓掌!