bash基礎

nh39304發表於2019-09-08

基礎知識:

    變數:  變數名+指向的記憶體空間;
    變數賦值:  var_name=value;
    變數型別: 
        資料儲存的格式,表示的資料範圍;
        字元型,數字型,布林型;
        C語音是強變數型別(使用前必須宣告型別,型別宣告後不能改變);bash是弱變數型別(無需事先宣告,
                型別隨需求改變);
        bash預設變數型別為字元型;
        要進行算術運算,需要宣告為數字型:
        declare -i  var_name
        變數引用:  ${var_name}   $var_name

算術運算:

       let VAR=expression;
       VAR= $[expression];
       VAR= $((expression));
       VAR= $(expr argu1 argu2 argu3 )
       注意:有些時候乘法符號需要用轉義字元;
       增強型賦值: += ,-= , *=, %=
       變數做某種運算後回存到此變數中
         let i=$i+n  ---> let i+=n  --->這個let的變數不用出現$
         let i+=1    ---> let i++
         let i-=i    ---> let i--

條件測試:	
    (1)執行命令,並利用命令返回狀態判斷, $?
       0: 成功  ,1~255失敗 
      指令碼的狀態返回值:預設是返回最後一條命名的狀態返回值
     自定義退出狀態碼:exit [n]:  n為指定的狀態碼
    (2)測試表示式
     test expression
     [ expression ]   ----注意expression兩邊必須有空白字元
     [[ expression ]]   
數值測試:
  -eq:  是否等於   [ $sum1  -eq  $sum2 ]
  -ne:  是否不等於
  -gt:  是否打於
  -ge:  是否大於等於
  -lt:  是否小於
  -le:  是否小於等於
字元測試:
  ==:  等於
  >:   大於
  <:   小於
  !=   不等於
注意: a.字串要加雙引號;
       b.字串測試要是有[[  ]];
          
          =~ : 左側字串是否能夠被右側的PATTERN所匹配;
          -z “string”: 判斷指定的字串是否為空,空為真;
          -n “string”: 判斷指定的字串是否為空,非空為真;
       
        檔案測試
           存在性測試:
             -a FILE  存在為真
             -e FILE  存在為真
           存在性及型別測試:
             -b FILE   塊檔案
             -c FILE   字元檔案
             -d FILE   目錄
             -f FILE   普通檔案
             -h FILE   符合連結檔案
             -P FILE   管道檔案(大寫P)
             -S FILE   套接字檔案(大寫S)
            
            檔案許可權性測試
             -r FILE   ;  -w FILE  ;-x FILE  ;
             -U FILE (suid許可權) ; -g FILE(sgid許可權); -K FILE(sticky許可權)
            檔案是否有內容
             -s FILE
            時間戳
             -N FILE 檔案自上一次讀後是否被修改過;
            從屬關係
             -O 當前使用者是否檔案的屬主
             -G 當前使用者是否檔案的屬組
            雙目測試
              FILE1 -ef FILE2  是否指向相同inode的硬連線
              FILE1 -nt FILE2  FILE1是否新於FILE2
              FILE1 -ot FILE2  FILE1是否舊於FILE2
組合測試條件
  邏輯運算
  (1)  
        COMMAND1 && COMMAND2
        可以這樣來使用:相當於if command1 is true then command2,
        因為先判斷command1,ture才會執行command2
     COMMAND1 || COMMAND2
          可以這樣來使用:相當於else,因為先判斷command1,command1是ture的話,就不執行command2了
     COMMAND1 !  COMMAND2
  (2) 
     EXPRESSION1 -a EXPRESSION2
     EXPRESSION1 -0 EXPRESSION2
     !EXPRESSION2
     注意: 邏輯運算子前後都有空白字元
     邏輯運算優先順序別 !> -a > -o, 改變級別用括號,括號要用轉義字元,前後留空

 示例:

logic_script.sh
#!/bin/bash
#
file=/tmp/logic_script.sh
  [ 6 -lt 7 ] && echo "1" || echo "0"
  [ "is a good day" =~ "day" ] && echo "1" || echo "0"   
  [ -a $file] && echo "1" || echo "0"          
[root@localhost tmp]# bash -x logic_script.sh 
+ file=/tmp/logic_scritp.sh           ---看||的邏輯,前面為真,後面就不執行了
+ '[' 6 -lt 7 ']'
+ echo 1
1
+ '[' isagoodday '=~' day ']'
logic_script.sh: line 6: [: =~: binary operator expected  ---字串比較要兩個中括號[[]]
+ echo 0
+ '[' -a '/tmp/logic_scritp.sh]'
logic_script.sh: line 7: [: missing `]'  ---看錯誤提示,]沒有空格隔開,變為missing `]'
+ echo 0
            
修改後: 
logic_script.sh  
#!/bin/bash
#
file=/tmp/logic_script.sh
  [ 6 -lt 7 ] && echo "1" || echo "0"
  [[ "isagoodday" =~ "day" ]] && echo "1" || echo "0"
  [ -a $file ] && echo "1" || echo "0"
[root@localhost tmp]# bash -x logic_script.sh 
+ file=/tmp/logic_script.sh
+ '[' 6 -lt 7 ']'
+ echo 1
1
+ [[ isagoodday =~ day ]]
+ echo 1
1
+ '[' -a /tmp/logic_script.sh ']'
+ echo 1
1

變數作用域            

 環境變數: 當前shell進行及子程式有效
                賦值: (1)export var_name=value
                       (2)var_name= value
                            export var_name
                       (3)declare -x var_name=value
                       (4)var_name=value
                            delare -x var_name
                       注意: bash內嵌了許多環境變數(通常全為大寫字母)
                檢視: export , declare -x  , env
                
            本地變數: 當前執行指令碼的shell進行的生命週期,對子shell無效
                賦值: var_name=value
                引用: ${var_name}  , $var_name
                檢視: set
                撤銷: unset var_name(此處不能用$)
                   
            
            區域性變數: 某程式碼的片段,如函式的上下文,作用在函式的生命週期,函式結束就銷燬;
                賦值: local var_name=vaule               
                             
            位置引數變數:當前執行指令碼的shell程式傳遞的引數
                使用方式:myscript argue1  argu2 argu3 ... --->執行指令碼時直接賦值給引數
                引用方式:$1 , $2  ,$3,...   
                
                輪替: shift n  把後面第n個引數輪替到第一個引數,n前面的引數都踢掉
                
            
                特殊變數:
                    $0: 指令碼檔名;
                    $#: 指令碼引數的個數
                    $*: 所有引數
                    $@: 所有引數   
                 --假設在指令碼執行時寫了三個引數 1、2、3
                    " * " 等價於 "1 2 3"(傳遞了一個引數),
                    "@" 等價於 "1" "2" "3"(傳遞了三個引數)
                    $$: 指令碼執行的當前程式ID號;
                    $!: 後臺執行的最後一個程式的ID號

 例子:
sum_scirp.sh             
#!/bin/bash
#
declare -i sum
echo "the script filename is: $0"
echo "the script argu is : $*"
echo "the script argu's number is : $#"
shift 2                     ---- 前連個引數被踢了
echo "the script argu is : $*"
echo "the script argu's number is : $#"
for ((i=1;i<=$#;i++));do    ----仿C語言風格的for迴圈,需要兩個括號
let sum+=$i;            ----$i,i迴圈的值,怎樣取傳遞引數的值$($i)?
done
echo "the sum is $sum"
    [root@localhost tmp]# bash sum_script.sh  1 2 13 14 15 16 17 18 9
the script argu is : 1 2 13 14 15 16 17 18 9
the script argu's number is : 9
the script argu is : 13 14 15 16 17 18 9    ---- shift 2 的效果
the script argu's number is : 7
the sum is 28                ---- 28=1+2+3+4+5+6+7 ,這個$i不是取傳遞引數的值!
修改for語句
    for i in $*;do
      echo "$i"
      let sum+=$i         ---- 這個$i是列表裡的資料,!
    done
[root@localhost tmp]# bash  sum_script.sh  1 2 13 14 15 16 17 18 9
the script argu is : 1 2 13 14 15 16 17 18 9
the script argu's number is : 9
the script argu is : 13 14 15 16 17 18 9
the script argu's number is : 7
13
14
15
16
17
18
9
the sum is 102


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69934036/viewspace-2656415/,如需轉載,請註明出處,否則將追究法律責任。

相關文章