歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> SHELL編程

系統管理中bash shell腳本常用方法總結

系統管理中bash shell腳本常用方法總結   在日常系統管理工作中,需要編寫腳本來完成特定的功能,編寫shell腳本是一個基本功了! 在編寫的過程中,掌握一些常用的技巧和語法就可以完成大部分功能了,也就是2/8原則.   1. 單引號和雙引號的區別   單引號與雙引號的最大不同在於雙引號仍然可以引用變量的內容,但單引號內僅是普通字符 ,不會作變量的引用,直接輸出字符竄。請看如下例子:     [root@linux ~]# name=HaHa    [root@linux ~]# echo $name    HaHa    [root@linux ~]# myname="$name is wow"    [root@linux ~]# echo $myname    HaHa is wow    [root@linux ~]# myname='$name is wow'    [root@linux ~]# echo $myname    $name is wow   從上面例子可以看出,使用了單引號的時候,那麼$name只是普通字符,直接輸出而已!   2. 逐行讀取文件   使用for循環來讀取文件   for line in `cat file.txt`   do   echo $line   done 注意:由於使用for來讀入文件裡的行時,會自動把空格和換行符作為一樣分隔符,如果行裡有空格的時候,輸出的結果會很亂,所以只適用於行連續不能有空格或者換行符的文件 使用while循環讀取文件   cat file.txt |while read line   do   echo $line   done      或者:      while read line   do   echo $line   done < file.txt 注意:由於使用while來讀入文件裡的行時,會整行讀入,不會關注行的內容(空格..),所以比for讀文件有更好的適用性,推薦使用while循環讀取文件 3. bash shell 腳本中常用隱含變量   $0 當前執行的腳本或者命令名稱 $1-$9 代表參數的位置. 舉例 $1 代表第一個參數. $# 腳本調用的參數的個數 $@ 所有參數的內容 $* 所有參數的內容 $$ 當前運行腳本的進程號 $? 命令執行後返回的狀態 $! 後台運行的最後一個進程號 注意: $? 用於檢查上一個命令執行是否正確(在Linux中,命令退出狀態為0表示該命令正確執行,任何非0值表示命令出錯)  $$ 變量最常見的用途是用做暫存文件的名字以保證暫存文件不會重復。  $* 和 $@ 如果輸出是一樣的,但是在使用for循環,在使用 雙引號("")引用時 "$*" 會輸出成一個元素 而 "$@" 會按照每個參數是一個元素方式輸出 請看測試例子     #cat test.sh    #!/bin/sh   echo '"$@" output.....'   for i in "$@"   do   echo $i   done   echo '"$*" output ....'   for i in "$*"   do       echo $i   done 輸出結果     #sh test.sh a b c d   "$@" output.....   a   b   c   d   "$*" output ....   a b c d 從輸出結果可以看出 "$*" 輸出是一行 而 "$@" 輸出則是四行 4. 變量內容的刪除與替換   我們在一些情況下,需要對變量中的字符竄進行查找刪除或者替換,就需要使用下表列出的方法   變量設定方式 說明 ${變量#關鍵字} 若變量內容從頭開始的資料符合‘關鍵字’,則將符合的最短資料刪除 ${變量##關鍵字} 若變量內容從頭開始的資料符合‘關鍵字’,則將符合的最長資料刪除 ${變量%關鍵字} 若變量內容從尾向前的資料符合‘關鍵字’,則將符合的最短資料刪除 ${變量%%關鍵字} 若變量內容從尾向前的資料符合‘關鍵字’,則將符合的最長資料刪除 ${變量/舊字串/新字串} 若變量內容符合‘舊字串’則‘第一個舊字串會被新字串取代 ${變量//舊字串/新字串} 若變量內容符合‘舊字串’則‘全部的舊字串會被新字串取代 舉例如下(刪除字符竄中的某個字符):     [root@linux ~]# export test_str="/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin"    [root@linux ~]# echo ${test_str#/*kerberos/bin:}   /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin 5. 變量條件測試賦值   在某些時刻我們需要‘判斷’某個變量是否存在,若變量存在則將此變量值賦值給新的變量,若變量不存在則將其他值賦值給新的變量.   變量設定方式 str 未定義 str 為空字串 str 已賦值為非空字串 var=${str-expr} var=expr var= var=$str var=${str:-expr} var=expr var=expr var=$str var=${str+expr} var= var=expr var=expr var=${str:+expr} var= var= var=expr var=${str?expr} expr 輸出至 stderr var= var=$str var=${str:?expr} expr 輸出至 stderr expr 輸出至 stderr var=$str var=${str=expr} var=expr var= var=$str var=${str:=expr} var=expr var=expr var=$str 舉例如下:     [root@linux ~]# test_name=""   [root@linux ~]# test_name=${test_name-root}   [root@linux ~]# echo $test_name         <== 因為 test_name 被設定為空字符竄!所以當然還是保留為空字符竄!   [root@linux ~]# test_name=${test_name:-root}   [root@linux ~]# echo $test_name   root  <== 加上‘:’後若變量內容為空或者是未設定,都能夠以後面的內容替換! 基本上這種變量的測試也能夠透過 shell script 內的 if...then... 來處理,不過通過上述提及的簡單的方法來測試變量,是程序看起來更精簡一些! 6. shell 中分隔符 : 變量IFS 使用   shell腳本中,如果使用for循環一個字符竄的話,默認使用空格來分割字符竄.還有前面所提到的 使用for循環逐行讀取文件內容時候,文件行中如果有空格的話輸出的結果也會變亂.這個時候 使用 IFS 變量來設置特定的字符竄分割符來,達到輸出正確的目的.默認情況下 IFS 是使用 <space><tab><newline>, 空格 \t \n 來作為默認的分割符的.   我們將前面使用for逐行讀取文件的例子 改進下就可以輸出正確了,請看下面     #!/bin/bash   IFS_old=$IFS      #將原IFS值保存,以便用完後恢復   IFS=$’\n’         #更改IFS值為$’\n’   for line in `cat file.txt`   do   echo $line   done file.txt 文件內容如下     [root@linux]$ cat file.txt    sdfsdfsdfsdf   ssssss ssssss ssssss sssss   sdfsdfsdfsdfsdf 執行測試程序 輸出結果如下(正確輸出)     [root@linux]$ sh test.sh    sdfsdfsdfsdf   ssssss ssssss ssssss sssss   sdfsdfsdfsdfsdf 如果未設置IFS變量,使用默認的IFS變量值 ,輸出結果如下     [root@linux]$ sh test.sh    sdfsdfsdfsdf   ssssss   ssssss   ssssss   sssss   sdfsdfsdfsdfsdf 從以上測試程序輸出結果,可以根據自己的需求來設定 IFS變量,在舉一個例子如下:     while IFS=: read userName passWord userID groupID geCos homeDir userShell   do         echo "$userName -> $homeDir"   done < /etc/passwd 7. shell 數組的使用   數組賦值方式:     (1) array=(var1 var2 var3 ... varN)   (2) array=([0]=var1 [1]=var2 [2]=var3 ... [n]=varN)   (3) array[0]=var1       arrya[1]=var2       ...       array[n]=varN 計算數組元素個數或者長度:     (1) ${#array[@]}       (2) ${#array[*]} 了解了數組基礎語法,舉例說明,請看:     #!/bin/bash   NAMESERVERS=("ns1.www.net." "ns2.www.net." "ns3.www.net.")   # 得到數組長度   tLen=${#NAMESERVERS[@]}       # 循環數組   for (( i=0; i<${tLen}; i++ ));   do     echo ${NAMESERVERS[$i]}   done 在看一個復雜一點的例子,將文件內容讀取到數組中:     #!/bin/bash      # 設置IFS將分割符 設置為 換行符(\n)   OLDIFS=$IFS   IFS=$'\n'        # 讀取文件內容到數組   fileArray=($(cat file.txt))       # restore it   IFS=$OLDIFS   tLen=${#fileArray[@]}       # 循環顯示文件內容   for (( i=0; i<${tLen}; i++ ));   do     echo "${fileArray[$i]}"   done 8. 邏輯判斷 條件測試   文件屬性的判斷 操作符 測試結果 -e filename 文件存在返回1, 否則返回0 -r filename 文件可讀返回1,否則返回0 -w filename 文件可寫返回1,否則返回0 -x filename 文件可執行返回1,否則返回0 -o filename 文件屬於用戶本人返回1, 否則返回0 -z filename 文件長度為0返回1, 否則返回0 -f filename 文件為普通文件返回1, 否則返回0 -d filename 文件為目錄文件時返回1, 否則返回0 舉例如下,測試文件是否存在:     #!/bin/bash   echo "checks the existence of the messages file."   echo -n "Checking..."   if [ -f /var/log/messages ];then       echo "/var/log/messages exists."   fi   echo   echo "...done." 字符串比較 操作符 比較結果 str1 = str2 當兩個字串相等時為真 str1 != str2 當兩個字串不等時為真 -n str1 當字符串的長度大於0時為真 -z str1 當字符串的長度為0時為真 str 當字符串為非空時為真 舉例如下,比較字符串來測試用戶ID :     if [ "$(whoami)" != 'root' ]; then           echo "You have no permission to run $0 as non-root user."           exit 1;   fi 數值比較(整數) 操作符 比較結果 num1 -eq num2 兩數相等為真 num1 -ne num2 兩數不等為真 num1 -gt num2 num1大於num2為真 num1 -ge num2 num1大於等於num2為真 num1 -lt num2 num1小於num2為真 num1 -le num2 num1小於等於num2為真 舉例如下:     num=`wc -l work.txt`   if [ $num -gt 150 ];then   echo "you've worked hard enough for today."   echo   fi 如果要查看詳細的測試操作,可以查看man手冊 man test
Copyright © Linux教程網 All Rights Reserved