<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 134,comments - 22,trackbacks - 0

    在日常系統管理工作中,需要編寫腳本來完成特定的功能,編寫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

    posted on 2010-09-30 10:54 何克勤 閱讀(935) 評論(0)  編輯  收藏 所屬分類: GNU Linux/Unix
    主站蜘蛛池模板: 免费一区二区三区四区五区 | 亚洲www77777| 秋霞人成在线观看免费视频| 亚洲乱码中文字幕久久孕妇黑人| 一级特黄aaa大片免费看| 亚洲高清无码综合性爱视频| 成人嫩草影院免费观看| 亚洲色欲久久久综合网| 国产麻豆成人传媒免费观看 | 日本最新免费不卡二区在线| 亚洲精品无码专区久久| 国产三级免费电影| CAOPORM国产精品视频免费| 亚洲熟女少妇一区二区| 免费国产成人午夜在线观看| 亚洲网站在线免费观看| 啦啦啦www免费视频| 日韩大片免费观看视频播放 | 亚洲一卡2卡4卡5卡6卡在线99| 99精品全国免费观看视频| 蜜芽亚洲av无码一区二区三区| 亚洲精品国产精品国自产观看 | 2017亚洲男人天堂一| 日本19禁啪啪无遮挡免费动图| 免费一级全黄少妇性色生活片| 亚洲成av人影院| 最近中文字幕免费mv视频8| 美女无遮挡免费视频网站| 亚洲精品午夜无码电影网| 91久久成人免费| 免费国产va在线观看| 亚洲国产精品久久久久| 青青草国产免费久久久91| 久久精品无码专区免费| 亚洲福利视频网址| 亚洲国产av一区二区三区| 亚洲电影免费在线观看| 色天使色婷婷在线影院亚洲| 亚洲V无码一区二区三区四区观看| 成年轻人网站色免费看| 免费萌白酱国产一区二区三区|