Bash Shell-基礎語法

#!/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
相關文章
相關標籤/搜索