收藏!一篇教會你寫90%的shell腳本!

{"type":"doc","content":[{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在公司項目的開發過程中,需要編寫shell腳本去處理一個業務,在編寫過程中發現自身對shell腳本的知識不夠完善,顧整理一下,本文章主要內容來自"},{"type":"link","attrs":{"href":"https://www.runoob.com/linux/linux-shell.html","title":""},"content":[{"type":"text","text":"菜鳥教程"}]},{"type":"text","text":" , 也添加了一些知識點"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"看完這邊文章應該就可以獨立完成大部分腳本得編寫"}]}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"shell腳本?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"在說什麼是shell腳本之前,先說說什麼是shell。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"shell是外殼的意思,就是操作系統的外殼。我們可以通過shell命令來操作和控制操作系統,比如Linux中的Shell命令就包括ls、cd、pwd等等。總結來說,Shell是一個命令解釋器,它通過接受用戶輸入的Shell命令來啓動、暫停、停止程序的運行或對計算機進行控制。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"shell 是一個應用程序,它連接了用戶和 Linux 內核,讓用戶能夠更加高效、安全、低成本地使用 Linux 內核,這就是 Shell 的本質。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"shell 本身並不是內核的一部分,它只是站在內核的基礎上編寫的一個應用程序。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"那麼什麼是shell腳本呢?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"shell腳本就是由Shell命令組成的執行文件,將一些命令整合到一個文件中,進行處理業務邏輯,腳本不用編譯即可運行。它通過解釋器解釋運行,所以速度相對來說比較慢。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"shell腳本中最重要的就是對shell命令的使用與組合,再使用shell腳本支持的一些語言特性,完成想要的功能。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"註釋"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"“# ”開頭的就是註釋,被編譯器忽略"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"單行註釋: # "}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"多行註釋: :< readonly name (使用readonly標識後的變量,不可被修改)"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"刪除變量: unset name; (刪除之後不可訪問,刪除不掉只讀變量)"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"字符串變量"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1)單引號"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"單引號變量"},{"type":"codeinline","content":[{"type":"text","text":"var='test'"}]},{"type":"text","text":" ,只能原樣輸出,變量無效"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"單引號中不能出現一個單獨的單引號,轉義也不可以"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2)雙引號"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"雙引號變量"},{"type":"codeinline","content":[{"type":"text","text":"var=\"my name is ${name}\""}]},{"type":"text","text":",變量有效"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可出現轉義符"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"3)拼接字符串"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"中間無任何+,之類的字符"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"name=\"this is\"\" my name\"; name=\"this is my name\"; name=\"this\" is \"my name\" 等效"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"name='this is'' my nam'; name='this is my name'; name='this' is 'my name' 等效"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"4)獲取字符串長度"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在${}中使用“#”獲取長度"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"name=\"test\";"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"echo ${#name}; # 輸出爲4"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"5)提取子字符串"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1:4 從第2個開始 往後截取4個字符"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"::4 從第一個字符開始 往後截取4個字符"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"name=\"this is my name\";"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"echo ${name:1:4} #輸出 his"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"echo ${name::4} #輸出 this"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"數組"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" bash只支持一維數組,不支持多維數組"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"定義數組:array_name=(li wang xiang zhang) (小括號做邊界、使用空格分離)"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"單獨定義數組的元素: array"},{"type":"text","marks":[{"type":"italic"}],"text":"para[0]=\"w\"; array"},{"type":"text","text":"para[3]=\"s\" (定義時下標不連續也可以)"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"賦值數組元素:array_name[0]=\"zhao\";"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"獲取數組元素:"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * array_name[0]=\"li\""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * array_name[3]=\"zhang\""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * echo ${array_name[0]} # 輸出\"li\""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * echo ${array_name[1]} # 輸出\" \""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * echo ${array_name[3]} # 輸出\"zhang\""}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * echo ${array_name[@]} # 輸出\"li zhang\" 輸出數組所有元素,沒有元素的下標省略"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"取得元素個數:${#array"},{"type":"text","marks":[{"type":"italic"}],"text":"name[@]} 或者 ${#array"},{"type":"text","text":"name[\\*]}"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"取得單個元素長度:${#array_name[1]}"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"參數傳遞"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"獲取參數值:"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * $0 : 固定,代表執行的文件名"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * $1 : 代表傳入的第1個參數"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * $n : 代表傳入的第n個參數"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"\\$#:參數個數"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"\\$\\"},{"type":"text","marks":[{"type":"italic"}],"text":": 以一個單字符串顯示所有向腳本傳遞的參數。如\"$\\"},{"type":"text","text":"\"用「\"」括起來的情況、以\"$1 $2 … $n\"的形式輸出所有參數"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"\\[email protected]:與$\\*相同,但是使用時加引號,並在引號中返回每個參數。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"\\$\\$:腳本運行的當前進程號"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"\\$!:後臺運行的最後一個進程的ID"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"\\$?: 顯示最後命令的退出狀態。0表示沒有錯誤,其他任何值表明有錯誤。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"\\$* 與 [email protected] 區別"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * 相同點:都是引用所有參數。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "},{"type":"text","marks":[{"type":"italic"}],"text":" 不同點:只有在雙引號中體現出來。假設在腳本運行時寫了三個參數 1、2、3,,則 \" "},{"type":"text","text":" \" 等價於 \"1 2 3\"(傳遞了一個參數),而 \"@\" 等價於 \"1\" \"2\" \"3\"(傳遞了三個參數)。 "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"運算符"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"算數運算"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"\\+ 、\\-、\\*、\\ : 乘號前必須加\\進行轉義纔可以進行乘法運算"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"加法運算"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * val=\\"},{"type":"codeinline","content":[{"type":"text","text":"expr 2 + 2\\"}]},{"type":"text","text":" (使用linux命令expr進行輔助運算) "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * val=$[2+2] (4個空格不是必要的,不同於條件判斷)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * val=$((2+2)) "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"數字關係運算符"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"關係運算符只支持數字,不支持字符串,除非字符串的值是數字。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"下面假定變量 a 爲 10,變量 b 爲 20"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-eq :檢測兩個數是否相等,相等返回 true。\t [ $a -eq $b ] 返回 false。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-ne:\t檢測兩個數是否不相等,不相等返回 true。\t [ $a -ne $b ] 返回 true。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-gt:\t檢測左邊的數是否大於右邊的,如果是,則返回 true。 \t[ $a -gt $b ] 返回 false。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-lt\t: 檢測左邊的數是否小於右邊的,如果是,則返回 true。\t [ $a -lt $b ] 返回 true。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-ge:\t檢測左邊的數是否大於等於右邊的,如果是,則返回 true。 \t[ $a -ge $b ] 返回 false。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-le\t: 檢測左邊的數是否小於等於右邊的,如果是,則返回 true。 \t[ $a -le $b ] 返回 true。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "},{"type":"text","marks":[{"type":"strong"}],"text":"字符串運算符"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"下表列出了常用的字符串運算符,假定變量 a 爲 \"abc\",變量 b 爲 \"efg\":"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" =\t:檢測兩個字符串是否相等,相等返回 true。\t[ $a = $b ] 返回 false。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"!=\t:檢測兩個字符串是否相等,不相等返回 true。\t[ $a != $b ] 返回 true。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-z\t:檢測字符串長度是否爲0,爲0返回 true。\t[ -z $a ] 返回 false。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-n\t:檢測字符串長度是否爲0,不爲0返回 true。\t[ -n \"$a\" ] 返回 true。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"$ :檢測字符串是否爲空,不爲空返回 true。\t[ $a ] 返回 true。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "},{"type":"text","marks":[{"type":"strong"}],"text":"布爾運算符"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"下表列出了常用的布爾運算符,假定變量 a 爲 10,變量 b 爲 20:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" !\t:非運算,表達式爲 true 則返回 false,否則返回 true。\t[ ! false ] 返回 true。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-o\t:或運算,有一個表達式爲 true 則返回 true。\t[ $a -lt 20 -o $b -gt 100 ] 返回 true。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-a\t:與運算,兩個表達式都爲 true 才返回 true。\t[ $a -lt 20 -a $b -gt 100 ] 返回 false。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"邏輯運算符"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以下介紹 Shell 的邏輯運算符,假定變量 a 爲 10,變量 b 爲 20:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"&&\t:邏輯的 AND\t[[ $a -lt 100 && $b -gt 100 ]] 返回 false"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"\\||\t:邏輯的 OR\t[[ $a -lt 100 || $b -gt 100 ]] 返回 true"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"文件運算符"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-b file\t:檢測文件是否是塊設備文件,如果是,則返回 true。\t[ -b $file ] 返回 false。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-c file\t:檢測文件是否是字符設備文件,如果是,則返回 true。\t[ -c $file ] 返回 false。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-d file\t:檢測文件是否是目錄,如果是,則返回 true。\t[ -d $file ] 返回 false。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-f file\t:檢測文件是否是普通文件(既不是目錄,也不是設備文件),如果是,則返回 true。\t[ -f $file ] 返回 true。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-g file\t:檢測文件是否設置了 SGID 位,如果是,則返回 true。\t[ -g $file ] 返回 false。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-k file\t:檢測文件是否設置了粘着位(Sticky Bit),如果是,則返回 true。\t[ -k $file ] 返回 false。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-p file\t:檢測文件是否是有名管道,如果是,則返回 true。\t[ -p $file ] 返回 false。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-u file\t:檢測文件是否設置了 SUID 位,如果是,則返回 true。\t[ -u $file ] 返回 false。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-r file\t:檢測文件是否可讀,如果是,則返回 true。\t[ -r $file ] 返回 true。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-w file\t:檢測文件是否可寫,如果是,則返回 true。\t[ -w $file ] 返回 true。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-x file :檢測文件是否可執行,如果是,則返回 true。\t[ -x $file ] 返回 true。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-s file\t:檢測文件是否爲空(文件大小是否大於0),不爲空返回 true。\t[ -s $file ] 返回 true。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"-e file\t:檢測文件(包括目錄)是否存在,如果是,則返回 true。\t[ -e $file ] 返回 true。"}]}]}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"執行相關"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"命令替換"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"命令替換與變量替換差不多,都是用來重組命令行的,先完成引號裏的命令行,然後將其結果替換出來,再重組成新的命令行。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"執行命令: "}]},{"type":"numberedlist","attrs":{"start":"1","normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":" \\"},{"type":"codeinline","content":[{"type":"text","text":"ls /etc\\"}]},{"type":"text","text":" : 反引號 (所有的unix系統都支持)"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"$(ls /etc) : $+() (部分unix系統不支持)"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"多個嵌套使用時,從內向外執行"}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"for file in \\s /etc\\ 或 for file in $(ls /etc) 循環中使用"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"\\"},{"type":"codeinline","content":[{"type":"text","text":"dirname \\$0\\"}]},{"type":"text","text":" 獲取腳本文件所在的目錄"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"path=$(cd \\"},{"type":"codeinline","content":[{"type":"text","text":"dirname $0\\"}]},{"type":"text","text":";pwd) : 獲取腳本當前所在目錄,並且執行cd命令到達該目錄,使用pwd獲取路徑並賦值到path變量"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"算術運算"}]},{"type":"numberedlist","attrs":{"start":"1","normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"$[ ] : 加減乘除,不必添加空格"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"$(( )) :加減乘除等,不必添加空格"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"邏輯判斷"}]},{"type":"numberedlist","attrs":{"start":"1","normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"\\[ ] : 中括號旁邊和運算符兩邊必須添加空格 (可以使用,不推薦)"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"[[ ]]:中括號旁邊和運算符兩邊必須添加空格 (字符串驗證時,推薦使用)"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"(()) : 中括號旁邊和運算符兩邊必須添加空格 (數字驗證時,推薦使用)"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":4,"align":null,"origin":null},"content":[{"type":"text","text":"[[]] 和 (()) 分別是[ ]的針對數學比較表達式和字符串表達式的加強版。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":5,"align":null,"origin":null},"content":[{"type":"text","text":"使用[[ ... ]]條件判斷結構,而不是[ ... ],能夠防止腳本中的許多邏輯錯誤。比如,&&、||、 操作符能夠正常存在於[[ ]]條件判斷結構中,但是如果出現在[ ]結構中的話,會報錯。比如可以直接使用if [[ $a != 1 && $a != 2 ]], 如果不適用雙括號, 則爲if [ $a -ne 1] && [ $a != 2 ]或者if [ $a -ne 1 -a $a != 2 ]。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[[ ]]中增加模式匹配特效;"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"(( ))不需要再將表達式裏面的大小於符號轉義,除了可以使用標準的數學運算符外,還增加了以下符號"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d0/d059c812652d73dde1aa387eb3308302.png","alt":"在這裏插入圖片描述","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"輸出"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"echo"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"僅用於字符串的輸出,沒有使用printf作爲輸出的移植性好,建議使用printf"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"printf"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":">printf 不會像 echo 自動添加換行符,我們可以手動添加 \\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":">無大括號,直接以空格分隔"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"格式:"},{"type":"codeinline","content":[{"type":"text","text":"printf format-string [arguments...]"}]},{"type":"text","text":" 其中(format-string: 格式控制字符串、arguments: 參數列表)"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"案例:"},{"type":"codeinline","content":[{"type":"text","text":"printf \"%-10s %-8s %-4.2f\\n\" 郭靖 男 66.1234 "}]}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"%s %c %d %f 都是格式替代符"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * d:Decimal 十進制整數 對應位置參數必須是十進制整數,否則報錯!"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * s:String 字符串 對應位置參數必須是字符串或者字符型 否則報錯"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * c:Char 字符 對應位置參數必須是字符串或者字符型 否則報錯"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * f:Float 浮點 對應位置參數必須是數字型 否則報錯"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"%-10s"}]},{"type":"text","text":" : 指一個寬度爲10個字符(-表示左對齊,沒有則表示右對齊),任何字符都會被顯示在10個字符寬的字符內,如果不足則自動以空格填充,超過也會將內容全部顯示出來。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"%-4.2f"}]},{"type":"text","text":" :指格式化爲小數,寬度爲4個字符,其中"},{"type":"codeinline","content":[{"type":"text","text":".2"}]},{"type":"text","text":"指保留2位小數。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"轉義符:"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * \\a\t:警告字符,通常爲ASCII的BEL字符"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * \\b\t:後退"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * \\c\t:抑制(不顯示)輸出結果中任何結尾的換行字符(只在%b格式指示符控制下的參數字符串中有效),而且,任何留在參數裏的字符、任何接下來的參數以及任何留在格式字符串中的字符,都被忽略"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * \\f\t:換頁(formfeed)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * \\n\t:換行"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * \\r\t:回車(Carriage return)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * \\t\t:水平製表符"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * \\v\t:垂直製表符"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * \\\\\t:一個字面上的反斜槓字符"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * \\ddd\t:表示1到3位數八進制值的字符。僅在格式字符串中有效"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * \\0ddd\t:表示1到3位的八進制值字符"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"流程控制"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"和Java、PHP等語言不一樣,sh的流程控制不可爲空,即if或者else的大括號中無任何語句"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"if else"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"if"}]}]}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"if condition\nthen\n command1 \n command2\n ...\n commandN \nfi"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"if else"}]}]}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"if condition\nthen\n command1 \n command2\n ...\n commandN\nelse\n command\nfi"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"if else-if else"}]}]}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"if condition1\nthen\n command1\nelif condition2 \nthen \n command2\nelse\n commandN\nfi"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"for"}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"for var in item1 item2 ... itemN\ndo\n command1\n command2\n ...\n commandN\ndone"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"while"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"while condition"}]}]}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"while condition\ndo\n command\ndone"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"while 無限循環"}]}]}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"while :\ndo\n command\ndone"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"until"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"until 循環執行一系列命令直至條件爲 true 時停止。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"until 循環與 while 循環在處理方式上剛好相反。"}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"until condition\ndo\n command\ndone"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"case"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Shell case語句爲多選擇語句。可以用case語句匹配一個值與一個模式,如果匹配成功,執行相匹配的命令。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"case需要一個esac(就是case反過來)作爲結束標記,每個case分支用右圓括號,用兩個分號表示break,其中“;;”不是跳出循環,是不在去匹配下面的模式"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"case語句格式如下:"}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"case 值 in\n 模式1)\n command1\n command2\n ...\n commandN\n ;;\n 模式2)\n command1\n command2\n ...\n commandN\n ;;\nesac"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"跳出循環"}]},{"type":"numberedlist","attrs":{"start":"1","normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"break :跳出總循環"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"continue:跳出當前循環,繼續下一次循環"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"定義函數"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以帶function fun() 定義,也可以直接fun() 定義,不帶任何參數。"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"函數定義"}]}]}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"[ function ] funname()\n{\n action;\n [return int;]\n}"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"參數傳遞"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * 調用函數: fun_name 2 3 4"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" "},{"type":"text","marks":[{"type":"italic"}],"text":" 函數中使用:和shell取用函數相同 $n $# $"},{"type":"text","text":" $? 或者加上{}"}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"funWithParam(){\n echo \"第一個參數爲 $1 !\"\n echo \"第二個參數爲 $2 !\"\n echo \"第十個參數爲 $10 !\"\n echo \"第十個參數爲 ${10} !\"\n echo \"第十一個參數爲 ${11} !\"\n echo \"參數總數有 $# 個!\"\n echo \"作爲一個字符串輸出所有參數 $* !\"}\nfunWithParam 1 2 3 4 5 6 7 8 9 34 73\necho $? \\# 判斷執行是否成功"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"函數返回值"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * return字樣可存在也可不存在"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * return 只能爲 return [0-255],此處的返回可作爲函數執行的狀態,通過$?獲取的便是這個返回值"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * 如果不加return , 則默認最後一條語句的執行狀態所爲函數執行狀態的返回值,如果最後一條語句執行成功,則$?爲0,否則不爲0"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"使用函數返回值"},{"type":"text","text":"(Janusgraph圖數據庫官方啓動服務腳本片段)"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * return返回的數字,只是作爲函數執行狀態的返回值,也就是接下來$?獲取的值"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" * 對於類似於下面的"},{"type":"codeinline","content":[{"type":"text","text":"BIN=\\"}]},{"type":"text","text":"abs_path\\``語句,獲取的是函數體內所有的echo、printf輸出組合成的一個字符串"}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"abs_path() {\n SOURCE=\"${BASH_SOURCE[0]}\"\n while [ -h \"$SOURCE\" ]; do\n DIR=\"$( cd -P \"$( dirname \"$SOURCE\" )\" && pwd )\"\n SOURCE=\"$(readlink \"$SOURCE\")\"\n [[ $SOURCE != /* ]] && SOURCE=\"$DIR/$SOURCE\"\n done\n echo \"test\" \n echo \"$( cd -P \"$( dirname \"$SOURCE\" )\" && pwd )\" \n # 此函數的兩個echo輸出會組合成一個字符串作爲下述BIN的值\n}\n\nBIN=`abs_path` # BIN賦值函數返回值,如果沒有return,則函數中所有的echo、printf輸出組合成一個字符串傳入BIN\npath=${BIN}/nodetool # 可直接使用"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"輸入輸出重定向"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一般情況下,每個 Unix/Linux 命令運行時都會打開三個文件:"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"標準輸入文件(stdin):stdin的文件描述符爲0,Unix程序默認從stdin讀取數據。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"標準輸出文件(stdout):stdout 的文件描述符爲1,Unix程序默認向stdout輸出數據。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"標準錯誤文件(stderr):stderr的文件描述符爲2,Unix程序會向stderr流中寫入錯誤信息。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"默認情況下,command > file 將 stdout 重定向到 file,command < file 將stdin 重定向到 file。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果希望執行某個命令,但又不希望在屏幕上顯示輸出結果,那麼可以將輸出重定向到 /dev/null:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"輸入重定向"}]},{"type":"numberedlist","attrs":{"start":"1","normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"bash.sh < file : 將腳本的輸入重定向到file,由file提供參數"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"輸出重定向"}]},{"type":"numberedlist","attrs":{"start":"1","normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"bash.sh > file : 將腳本的輸出數據重定向到file中,覆蓋數據"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"bash.sh >> file : 將腳本的輸出數據重定向到file中,追加數據"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":" command >> file 2>&1 : 將 stdout 和 stderr 合併後重定向到 file"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"讀取外部輸入"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"命令:"},{"type":"codeinline","content":[{"type":"text","text":"read arg"}]},{"type":"text","text":" (腳本讀取外部輸入並賦值到變量上)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在shell腳本執行到上述命令時,停止腳本執行並等待外部輸入,將外部輸入賦值到arg變量上,繼續執行腳本"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"文件引用"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"引用其他的文件之後,可以使用其變量、函數等等,相當於將引用的文件包含進了當前文件"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"兩種方式:"}]},{"type":"numberedlist","attrs":{"start":"1","normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"."},{"type":"text","text":" file"},{"type":"text","marks":[{"type":"italic"}],"text":"path\\file"},{"type":"text","text":"name"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"source"},{"type":"text","text":" file"},{"type":"text","marks":[{"type":"italic"}],"text":"path\\file"},{"type":"text","text":"name"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"顏色標識"}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"printf \"\\033[32m SUCCESS: yay \\033[0m\\n\";\nprintf \"\\033[33m WARNING: hmm \\033[0m\\n\";\nprintf \"\\033[31m ERROR: fubar \\033[0m\\n\";"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"輸出結果:"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/72/72bea1512f1619bd0736376e2dc256eb.png","alt":"在這裏插入圖片描述","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"長句換行"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在shell中爲避免一個語句過長,可以使用“\\”進行換行"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用“\\”換行,在腳本執行過程中還是當做一行一個語句執行,不同於enter直接換行"}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"注意:\\ 前添加一個空格 。 \\ 後無空格直接換行。"}]}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":" /mysql/bin/mysql \\\n -h test_host -P 000 \\\n -u test_user -ptest_password ;"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"shell操作mysql"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"下面案例爲登錄mysql,並選擇操作數據庫,之後進行導入數據"}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":" /mysql/mysql/bin/mysql \\\n -h test_host -P 000 \\\n -u test_user -ptest_password \\\n -e\"use test_database; source data_faile; \" # -e 代表執行sql語句"}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" -u 用戶名 "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" -p 用戶密碼 "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" -h 服務器ip地址 "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" -D 連接的數據庫"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" -N 不輸出列信息 "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" -B 使用tab鍵 代替 分隔符 "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" -e 執行的SQL語句"}]}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"退出腳本"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"命令:"},{"type":"codeinline","content":[{"type":"text","text":"exit"}]},{"type":"text","text":" "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在退出腳本時使用不同的錯誤碼,這樣可以根據錯誤碼來判斷髮生了什麼錯誤。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":">在絕大多數 shell 腳本中,exit 0 表示執行成功,exit 1 表示發生錯誤。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對錯誤與錯誤碼進行一對一的映射,這樣有助於腳本調試。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"命令:"},{"type":"codeinline","content":[{"type":"text","text":"set -e 或者 set +e"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"set -e表示從當前位置開始,如果出現任何錯誤都將觸發exit。相反,set +e表示不管出現任何錯誤繼續執行腳本。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":">如果腳本是有狀態的(每個後續步驟都依賴前一個步驟),那麼請使用set -e,在腳本出現錯誤時立即退出腳本。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果要求所有命令都要執行完(很少會這樣),那麼就使用set +e。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"shell腳本調試"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"檢查是否有語法錯誤"},{"type":"codeinline","content":[{"type":"text","text":"-n"}]},{"type":"text","text":":"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"bash -n script_name.sh"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使用下面的命令來執行並調試 Shell 腳本"},{"type":"codeinline","content":[{"type":"text","text":"-x"}]},{"type":"text","text":":"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"bash -x script_name.sh"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"調試count_odd_number.sh 程序案例:"}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"#!/usr/bin.env bash\n\n# 用於計算數組中奇數的和\n# @author liyangyang\n# @time 2019/09/17\n\nsum=0\nfor num in 1 2 3 4;do\n re=${num}%2\n if (( ${re} == 1 ));then\n sum=$[${sum}+${num}]\n fi\ndone\necho ${sum}"}]},{"type":"numberedlist","attrs":{"start":"1","normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"首先檢查有無語法錯誤:"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"bash -n count_odd_number.sh"}]}]},{"type":"numberedlist","attrs":{"start":"2","normalizeStart":"2"},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"沒有輸出,說明沒有錯誤,開始實際調試:"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"bash -x count_odd_number.sh"}]}]},{"type":"numberedlist","attrs":{"start":"3","normalizeStart":"3"},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"調試結果如下:"}]}]}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"+ sum=0\n+ for num in 1 2 3 4\n+ re=1%2\n+ (( 1%2 == 1 ))\n+ sum=1\n+ for num in 1 2 3 4\n+ re=2%2\n+ (( 2%2 == 1 ))\n+ for num in 1 2 3 4\n+ re=3%2\n+ (( 3%2 == 1 ))\n+ sum=4\n+ for num in 1 2 3 4\n+ re=4%2\n+ (( 4%2 == 1 ))\n+ echo 4\n4"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"其中的輸出顯示了程序執行的每一步,通過觀察程序執行的步驟是否滿足預期從而達到調試的效果"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"帶有 + 表示的是 Shell 調試器的輸出,不帶 + 表示程序的輸出。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"案例:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這是es(ElasticSearch)官方啓動服務的腳本,看可不可以理解吧~"}]},{"type":"codeblock","attrs":{"lang":"shell"},"content":[{"type":"text","text":"#!/usr/bin/env bash\n\n# CONTROLLING STARTUP:\n#\n# This script relies on a few environment variables to determine startup\n# behavior, those variables are:\n#\n# ES_PATH_CONF -- Path to config directory\n# ES_JAVA_OPTS -- External Java Opts on top of the defaults set\n#\n# Optionally, exact memory values can be set using the `ES_JAVA_OPTS`. Note that\n# the Xms and Xmx lines in the JVM options file must be commented out. Example\n# values are \"512m\", and \"10g\".\n#\n# ES_JAVA_OPTS=\"-Xms8g -Xmx8g\" ./bin/elasticsearch\n\nsource \"`dirname \"$0\"`\"/elasticsearch-env\n\nparse_jvm_options() {\n if [ -f \"$1\" ]; then\n echo \"`grep \"^-\" \"$1\" | tr '\\n' ' '`\"\n fi\n}\n\nES_JVM_OPTIONS=\"$ES_PATH_CONF\"/jvm.options\n\nES_JAVA_OPTS=\"`parse_jvm_options \"$ES_JVM_OPTIONS\"` $ES_JAVA_OPTS\"\n\n# manual parsing to find out, if process should be detached\nif ! echo $* | grep -E '(^-d |-d$| -d |--daemonize$|--daemonize )' > /dev/null; then\n exec \\\n \"$JAVA\" \\\n $ES_JAVA_OPTS \\\n -Des.path.home=\"$ES_HOME\" \\\n -Des.path.conf=\"$ES_PATH_CONF\" \\\n -cp \"$ES_CLASSPATH\" \\\n org.elasticsearch.bootstrap.Elasticsearch \\\n \"[email protected]\"\nelse\n exec \\\n \"$JAVA\" \\\n $ES_JAVA_OPTS \\\n -Des.path.home=\"$ES_HOME\" \\\n -Des.path.conf=\"$ES_PATH_CONF\" \\\n -cp \"$ES_CLASSPATH\" \\\n org.elasticsearch.bootstrap.Elasticsearch \\\n \"[email protected]\" \\\n /dev/null ; then\n exit 1\n fi\n exit 0\nfi\n\nexit $?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"推薦閱讀:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://liyangyang.blog.csdn.net/article/details/100939749","title":""},"content":[{"type":"text","text":"Git-【技術乾貨】工作中Git的使用實踐"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://liyangyang.blog.csdn.net/article/details/101035399","title":""},"content":[{"type":"text","text":"Git - 使用git不知道內部實現機制怎麼行"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"如果感覺這篇文章對您有所幫助,請點擊一下“喜歡”或者“關注”博主,您的喜歡和關注將是我前進的最大動力!謝謝大家~"}]}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章