#!/bin/bash ################################################################################ # Filename : basic_grammar.sh # Summary : Shell腳本的基礎語法 # License : GPL # Version : 1.0 # Author : Jet Bi # Email : 1207501666@qq.com # Date : 2008/08/08 # Notes : - ################################################################################ #------------------------------------------------------------------------------- # 編碼規範 # # 1.文件名、變量名、函數名用小寫字母、數字和下劃線組成,長度不超過20個字符 # 2.命名要避免使用Linux關鍵字、保留字 #------------------------------------------------------------------------------- #------------------------------------------------------------------------------- # 輸入與輸出 #------------------------------------------------------------------------------- # 示例1: 接收用戶輸入 read -p "Please input!" -t 30 input_cont echo "Content:"input_cont # 示例2: 輸出內容 echo "Hello,World!" #------------------------------------------------------------------------------- # 變量聲明 declare/typeset # # 語法: # declare [-/+] [aixrp] [變量] 或 declare -f # 參數說明: # -/+ :"-"能夠用來聲明變量 "+"取消該聲明 # a : 將變量聲明爲數組類型 # i : 將變量聲明爲整型 # x : 將變量聲明爲環境變量,至關於: export 變量 # r : 將變量聲明爲只讀變量,至關於: readonly 變量 # p : 顯示變量的聲明方式 #------------------------------------------------------------------------------- # 示例1: 聲明整型變量能夠直接作算數運算 declare -i sum=1+2 echo $sum #==>輸出結果:3 sum=1+2 echo $sum #==>輸出結果: 1+2 #------------------------------------------------------------------------------- # 字符串 # # 單引號 # 單引號裏的任何字符都會原樣輸出,單引號中的變量是無效的 # 單引號裏面不能出現單引號,轉義的單引號也不行 # 雙引號 # 雙引號裏能夠有變量 # 雙引號裏能夠出現轉義字符 #------------------------------------------------------------------------------- # 示例1: 字符串拼接 prefix="prefix" suffix="suffix" echo ${prefix}${suffix} #==>輸出結果: prefixsuffix # 示例2: 字符串截取:從第二個字符開始截取4個字符 # 第一個數字1爲索引,起始爲0,表示從1開始截取 # 第二個數字4爲長度,表示截取4個字符 str_split="Hello,World!" echo ${str_split:1:4} #==>輸出結果: ello # 示例3: 獲取字符串長度 str_len="" echo ${#str_len} #==>輸出結果: 5 # 示例4: 查找字符串 str_index="Hello,index!" echo $(expr index ${str_index} ,) #==>輸出結果: 6 #------------------------------------------------------------------------------- # 數組 # # bash只支持一維數組(不支持多維數組),而且沒有限定數組的大小,數組元素下標從0開始 # 注: 定義數組的時候各元素之間要用空格分隔 #------------------------------------------------------------------------------- # 示例1: 定義數組 array=("one" "two" "three" "four") #或 declare -a array=("one" "two" "three" "four") #或 array[0]="one" array[1]="two" array[2]="three" array[3]="four" # 示例2: 讀取數組 echo ${array[2]} #==>輸出結果: three echo ${array[@]} #==>輸出結果: one,two,three,four #獲取數組長度 echo ${#array[@]} #------------------------------------------------------------------------------- # 運算符 # # 算數運算符(+ 加法 - 減法 * 乘法 / 除法 % 取模 ) # 原生bash不支持簡單的數學運算,可是能夠經過其餘命令來實現 # 1.整數的運算用: expr 或 $(()) # 2.浮點數的運算用: bc 或 awk # test命令/[] 運算符 # test 命令 通常用簡寫的[]代替,能夠用來進行邏輯運算和文件、字符串的測試 # 1.關於某個文件名的"文件類型"判斷 # -e 檢測文件名是否存在,若是存在,則返回true # -f 檢測文件名是否存在且爲文件,若是是文件,則返回true # -d 檢測文件名是否存在且爲目錄,若是是目錄,則返回true # -L 檢測文件名是否存在且爲連接文件,若是是連接文件,則返回true # -s 檢測文件是否爲空(文件大小是否大於0),若是不爲空文件,則返回true # 2.關於文件的權限檢測(root權限常有例外) # -r 檢測文件是否存在且具備可讀權限,若是可讀,則返回true # -w 檢測文件是否存在且具備可寫權限,若是可寫,則返回true # -x 檢測文件是否存在且具備可執行權限,若是可執行,則返回true # 3.關於兩個整數之間的斷定 # -gt 大於 # -ge 大於等於 # -lt 小於 # -le 小於等於 # -eq 等於 # -ne 不等於 # 4.多重條件斷定 # -a 與 兩個條件同時成立 # -o 或 任何一個條件成立 # ! 非 取反向狀態 # 5.關於字符串的判斷,若是使用變量要用引號括起來,不然會報錯或判斷不許確 # -z 判斷字符串長度是否爲0,若爲空字符串,則爲true # -n 判斷字符串長度是否不爲0,若字符串不爲空,則爲true # == 判斷兩個字符串是否相等(用一個等號也能夠,至於區別嘛,不知道) # != 判斷兩個字符串是否不相等 # [[]] 運算符 test命令的加強版 # [[]]的使用與test命令的使用方式相同,但[[]]可以支持的功能更多,容錯也更高 # 1.支持更多的運算符,其語法更符合變成習慣: # > 大於 >= 大於等於 < 小於 <=小於等於 == 等於 != 不等於 # && 與 || 或 ! 非 # 2.容錯高 # 在關於字符串的判斷時,若是使用變量進行判斷 # []則須要使用引號括起來,不然可能報錯或判斷不許確 # [[]]則能夠經過判斷 # 3.支持字符串的模式匹配 # 好比 [[ hello == hell? ]] 的結果爲真 # 使用 =~ 操做符時甚至支持shell的正則表達式 #------------------------------------------------------------------------------- # 示例1: 整數的運算 num_a=1 num_b=2 echo $((${num_a}+${num_b})) #==>輸出結果: 3 echo $(expr ${num_a} + ${num_b}) #==>輸出結果: 3 echo $(expr ${num_a}+${num_b}) #==>輸出結果: 報錯,要注意空格 # 示例2: 浮點數的運算 num_a=1.258 num_b=2.369 echo $(echo "$num_a*$num_b"|bc -l) #==>輸出結果: 2.980202 echo $(echo "$num_a*$num_b"|bc) #==>輸出結果: 2.980 (會失真) echo $(awk -v a=${num_a} -v b=${num_b} 'BEGIN{print a * b}') #==>輸出結果: 2.9802 (也會失真,C語言,暫緩研究) # 示例3: 文件檢測之判斷文件是否存在 if [ -e /local/script/restart_tomcat.sh ]; then echo "文件存在" else echo "文件不存在" fi #或 if [[ -e /local/script/restart_tomcat.sh ]]; then echo "文件存在" else echo "文件不存在" fi # 示例4:判斷數字的大小,不推薦用[],由於貌似不支持浮點數 one=1.2 two=2.3 if [[ ${one} < ${two} ]]; then echo "one < two" else echo "one > two" fi # 示例5: 判斷兩個字符串是否相等,不推薦用[],容易出問題 str_a="" str_b="not empty" if [[ ${str_a} == $[str_b} ]]; then echo true else echo false fi #或 if [ "${str_a}" == "$[str_b}" ]; then echo true else echo false fi #注: 使用變量的時候必定要用引號括起來,不然就可能報錯 # 示例6: 判斷同時符合兩個條件 num=7 if [[ ${num} > 0 && ${num} < 10 ]]; then echo "num 是一個0-10之間的整數" else echo "num 不是一個0-10之間的整數" fi #------------------------------------------------------------------------------- # 流程控制: if條件判斷語句 # 注:bash的流程控制不可爲空,沒有就不要寫 # # 語法1: # if 條件判斷式; then # 當條件判斷式成立時,能夠進行的命令工做內容 # fi # 語法2: # if 條件判斷式一; then # 當條件判斷式一成立時候,能夠進行的命令工做內容 # elif 條件判斷式二; then # 當條件判斷式二成立時候,能夠進行的命令工做內容 # else # 當條件判斷一和條件判斷式二均不成立時,能夠進行的命令工做內容 # fi #------------------------------------------------------------------------------- # 示例1: 判斷字符串是否爲空 empty="" if [[ ${empty} ]]; then echo "字符串非空,內容爲:"${empty} else echo "字符串爲空" fi #------------------------------------------------------------------------------- # 流程控制: case...esac多選擇語句 # # 語法: # case $變量名稱 in # "第一個變量內容") # 程序段 # ;; # "第二個變量內容") # 程序段 # ;; # 」第n個變量內容") # 程序段 # ;; # *) # 不包含以上任何變量內容的其餘程序執行段 # ;; # esac #------------------------------------------------------------------------------- # 示例1:讀取用戶輸入的數字並翻譯成英文 read -p "Please input 1-10,This program will translate:" input case ${input} in "1") echo "1 ======> One" ;; "2") echo "2 ======> Two" ;; "3") echo "3 ======> Three" ;; "4"|"5") echo "4|5 ======> Four or Five" ;; *) echo "I don't know!" ;; esac #------------------------------------------------------------------------------- # 流程控制: while循環 until循環 # # 語法1 : # while 循環條件判斷式; do # 當循環條件判斷式成立時執行的循環體 # done # 語法2: # until 循環條件判斷式; do # 當循環條件判斷式不成立時執行的循環體(與while恰好相反,極少數狀況下用) # done #------------------------------------------------------------------------------- # 示例1:while循環打印數字1-5 var=1 while [[ ${var} <= 5 ]]; do echo "while循環==>"${var} var=$(($var+1)) done # 示例2:until循環打印數字1-5 var=1 until [[ ${var}>5 ]]; do echo "until循環==>"${var} let "var++" done #------------------------------------------------------------------------------- # 流程控制: for循環 # # 語法1 : # for 變量 in 項; do # 當變量在項內是執行的循環體 # done # 注:這個項能夠是一個序列,數組,參數列表,目錄列表甚至是字符串 # 語法2 :C風格 # for (( 初始值; 限制值; 執行步長 )); do # 當變量的值在限制值範圍內執行的循環體 # done #------------------------------------------------------------------------------- # 示例1:循環遍歷固定的幾個值 for var in 1 2 3 4 5; do echo "for循環示例1===>"${var} done # 示例2:循環一個列表 for var in {1..10}; do echo "for循環示例2===>"${var} done # 示例3:循環一個命令的執行結果 seq 序列 for var in $(seq 1 15); do echo "for循環示例3===>"${var} done # 示例4:循環一個命令的執行結果 ls 遍歷目錄 for var in $(ls /local); do echo "for循環示例4===>"${var} done # 示例5:循環一個數組 arr=("Jack" "Tom" "Jerry" "Rose" "Lucy") for var in ${arr[@]}; do echo "for循環示例5===>"${var} done # 示例6:C風格循環,可沒必要在乎裏面的先後是否要有空格,無限循環 ((;;)) for (( i=1; i<=20; i++ )); do echo "for循環示例6===>"${i} done # 示例7:不在乎空格依然不會出錯,這裏步長爲2 for (( i = 1; i<=25;i=i+2)); do echo "for循環示例7===>"${i} done #------------------------------------------------------------------------------- # 流程控制: break continue 跳出循環 # # 1.break n:n爲數字,默認爲1,即向外跳幾層循環,所處循環位置=循環結構總數-n # 若是n大於循環結構總數,則是跳出全部循環 # 2.continue n:n爲數字,默認爲1,和break不一樣的是,跳出本次循環進入下一次循環 # 若是n大於循環結構總數,則是跳到最外層循環 # 3.在n不大與循環結構總數,且循環總數不小於2的狀況下 # break n 與 continue n+1的循環執行次數是同樣的 # 4.通常循環不會太多層,兩層就夠TM多了,因此通常break和continue只用默認值 #----------------------------------------------------------------------------- stopflag="run" count=0 run="disabled" for one in $(seq 1 10); do if [ ${run} == "disabled" ]; then break fi let "count++" if [ ${stopflag} == "stop" ]; then echo "跳到了第一層循環內" stopflag="run" fi echo "這是第一層循環" for two in $(seq 1 10); do let "count++" if [ ${stopflag} == "stop" ]; then echo "跳到了第二層循環內" stopflag="run" fi echo "這是第二層循環" for three in $(seq 1 10); do let "count++" if [ ${stopflag} == "stop" ]; then echo "跳到了第三層循環內" stopflag="run" fi echo "這是第三層循環" for four in $(seq 1 10); do let "count++" echo "這是第四層循環" if [ ${four} -eq 4 ]; then stopflag="stop" continue 100 fi done done done done echo "執行的循環的總次數:===>"${count} #------------------------------------------------------------------------------- # 函數 # # 語法: # function funname(){ # 函數體 # [return int;] # } # 注意: # ()中不能夠有參數 #------------------------------------------------------------------------------- # 示例1: 函數的定義與調用 #定義 function print_hello(){ echo "Hello" } #調用 print_hello # 示例2: 給函數傳遞參數 function print_args(){ echo "傳遞的第一個參數:"$1 echo "傳遞的第二個參數:"$2 echo "傳遞的第三個參數:"$3 echo "傳遞的全部參數:"$@ } #調用 print_args one two three