乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Unix系列shell程序編寫(中)

       looline 2006-12-30

      3>在Shell中使用數(shù)據(jù)變量
        用戶可以在Shell中使用數(shù)據(jù)變量,例如ba.sh程序:
          cd/usr/icewalk
          ls|cpio -o > /dev/fd0

        該程序中要備份的目錄為一常量,即該程序只能用來備份一個目錄。若在該程序中使用變量,則會使其更通用:

          workdir=$1
          cd $workdir
          ls * |cpio -o > /dev/fd0

        通過這一改變,用戶可以使用程序備份變量$workdir指定的目錄。例如我們要備份/home/www的內(nèi)容,只要運(yùn)行ba.sh /home/www即可實(shí)現(xiàn)。(若不明白 $1,下面將詳細(xì)介紹shell參數(shù)的傳遞,$1代表本sh程序-ba.sh的第一個參數(shù))

        4>在Shell程序中加上注釋

        為了增加程序的可讀性,我們提倡加入注釋。在Shell程序中注釋將以"#"號開始。當(dāng)Shell解釋到"#"時,會認(rèn)為從"#"號起一直到該行行尾為注釋。

        5>對Shell變量進(jìn)行算術(shù)運(yùn)算

        高級語言中變量是具有類型的,即變量將被限制為某一數(shù)據(jù)類型,如整數(shù)或字符類型。Shell變量通常按字符進(jìn)行存儲,為了對Shell變量進(jìn)行算術(shù)運(yùn)算,必須使用expr命令。

        expr命令將把一個算術(shù)表達(dá)式作為參數(shù),通常形式如下:

          expr [數(shù)字] [操作符] [數(shù)字]

        由于Shell是按字符形式存儲變量的,所以用戶必須保證參加算術(shù)運(yùn)算的操作數(shù)必須為數(shù)值。下面是有效的算術(shù)操作符:

          +   兩個整數(shù)相加
          -   第一個數(shù)減去第二個數(shù)
          *   兩整數(shù)相乘
          /   第一個整數(shù)除以第二個整數(shù)
          %   兩整數(shù)相除,取余數(shù)
        例如:
          $expr 2 + 1
           結(jié)果顯示:3
          $expr 5 - 3
           結(jié)果顯示:2若expr的一個參數(shù)是變量,那么在表達(dá)式計算之前用變量值替換變量名。
          $int=3
          $expr $int + 4
          結(jié)果顯示:7
        用戶不能單純使用"*"做乘法,若輸入:
          $expr 4*5
        系統(tǒng)將會報錯,因為Shell看到"*"將會首先進(jìn)行文件名替換。正確形式為:
          $expr 4 \* 5
           結(jié)果顯示:20
        多個算術(shù)表達(dá)式可以組合在一起,例如:
          $expr 5 + 7 / 3
          結(jié)果顯示:7
        運(yùn)算次序是先乘除后加減,若要改變運(yùn)算次序,必須使用"`"號,如:
          $int=`expr 5 + 7`
          $expr $int/3
           結(jié)果顯示:4
          或者:
          $expr `expr 5+7`/3
          結(jié)果顯示:4

        6>向Shell程序傳遞參數(shù)

        一個程序可以使用兩種方法獲得輸入數(shù)據(jù)。一是執(zhí)行時使用參數(shù)。另一種方法是交互式地獲得數(shù)據(jù)。vi編輯程序可以通過交互式的方法獲得數(shù)據(jù),而ls和expr則從參數(shù)中取得數(shù)據(jù)。以上兩種方法Shell程序都可以使用。在"交互式讀入數(shù)據(jù)"一節(jié)中將介紹Shell程序通過交互式的方法獲得參數(shù)。

        通過命令行給Shell程序傳遞參數(shù)可以擴(kuò)大程序的用途。以前面提到的ba.sh程序為例:
        $cat >re.sh
        cd $workdir
        cpio -i < /dev/fd0
        ^d

        程序re.sh恢復(fù)了ba.sh程序備份的所有文件。若只從軟盤上恢復(fù)一個指定的文件,可以用該文件名作為參數(shù),傳遞給Shell程序re.sh:

        程序改寫如下:
        $cat >re2.sh
        cd $workdir
        cpio -i $1 < /dev/fd0
        ^d

        用戶可以指定要恢復(fù)的文件,例如fname

        $re2.sh fname

      此時文件fname作為第一個位置參數(shù)傳遞給re2.sh,re2.sh的缺點(diǎn)是要恢復(fù)兩個或多個文件要重復(fù)運(yùn)行,我們可以用$*變量傳遞不確定的參數(shù)給程序:

        $cat >re3.sh
        cd $workdir
        cpio -i $* < /dev/fd0
        ^d

        我們就可以恢復(fù)多個文件,例如fname1,fname2,fname3
        $re3.sh fname1 fname2 fname3
        (以上程序re.sh,re2.sh,re3.sh,假設(shè)用戶已經(jīng)chmod了可執(zhí)行權(quán)利)

        因為沒有賦值的變量可以作為NULL看待,所以若是程序re3.sh在執(zhí)行時候沒賦予參數(shù),那么一個空值將被插入到cpio命令中。該命令將恢復(fù)所有保存的文件。

      條件判斷語句

        條件判斷語句是程序設(shè)計語言中十分重要的語句,該語句的含義是當(dāng)某一條件滿足時,執(zhí)行指定的一組命令。

      1>if - then語句

        格式: if command1
           then
             command2
             command3
           fi      ---(if 語句結(jié)束)
             command4

        每個程序或命令執(zhí)行結(jié)束后都有一個返回的狀態(tài),用戶可以用Shell變量$?獲得這一狀態(tài)。if語句檢查前面命令執(zhí)行的返回狀態(tài),若該命令成功執(zhí)行,那么在then和fi之間的命令都將被執(zhí)行。在上面的命令序列中,command1和command4總要執(zhí)行。若command1成功執(zhí)行,command2和command3也將執(zhí)行。

        請看下面程序:
          #unload -program to backup and remove files
          cd $1
          ls -a | cpio -o > /dev/mnt0
          rm *

        該程序在備份資料后,刪除檔案,但當(dāng)cpio命令不能成功執(zhí)行時,rm命令還是把資料刪除了,我們可不希望這樣,為了避免此情況,可以用if - then語句:
          #--卸載和判斷刪除程序

          cd $1
          if ls -a | cpio > /dev/mnt0
          then
            rm *
          fi
        上面程序在cpio執(zhí)行成功后才刪除檔案

      同時,若執(zhí)行沒有成功,我們希望得到提示,sh中的echo命令可以向用戶顯示消息,并顯示后換行,上面程序可以寫成:
           #--卸載和判斷刪除程序
          cd $1
          if ls -a | cpio > /dev/mnt0
          then
            echo "正刪除文件資料... ..."
            rm *
          fi

        echo命令可以使用一些特殊的逃逸字符進(jìn)行格式化輸出,下面是這些字符及其含義:

          \b  Backspace
          \c  顯示后不換行
          \f  在終端上屏幕的開始處顯示
          \n  換行
          \r  回車
          \t  制表符
          \v  垂直制表符
          \   反斜框
          \0nnn 用1,2或3位8進(jìn)制整數(shù)表示一個ASCII碼字符

      2>if - then - else語句

        不用多說它的作用,別的高級語言中都有,格式為:
        if command1
        then
          command2
          command3
        else
          command4
          command5
        fi

        在此結(jié)構(gòu)中,command1中是先執(zhí)行,當(dāng)command1成功執(zhí)行時,將執(zhí)行command2和command3,否則執(zhí)行command4和command5

        注意看下面程序:
          #備份程序
          cd $1
          if ls -a |cpio -o > /dev/mnt0
          then
            echo "刪除源資料... ..."
            rm *
          else
            echo "磁帶備份失敗!"
          fi

      3>test命令進(jìn)行條件測試

        if語句可以通過測試命令執(zhí)行的返回狀態(tài)來控制命令的執(zhí)行,若要測試其他條件,在bsh中可以使用test命令。該命令檢測某一條件,當(dāng)條件為真時返回0,否則返回非0值。test命令可以使Shell程序中的if語句象其他程序語言中的條件判斷語句一樣,具有很強(qiáng)的功能。

        test命令的使用方法為:
          test condition
        可測試的條件分為4類:
        1)測試兩個字符串之間的關(guān)系。
        2)測試兩個整數(shù)之間關(guān)系。
        3)測試文件是否存在或是否具有某種狀態(tài)或?qū)傩浴?
        4)測試多個條件的與(and)或(or)組合。

      1、條件語句>>test語句

      1>測試字符串間的關(guān)系

        bsh把所有的命令行和變量都看作字符串。一些命令如expr和test可以把字符當(dāng)作數(shù)字進(jìn)行操作。

        同樣任何數(shù)字也可以作為字符串進(jìn)行操作。

        用戶可以比較兩個字符串相等或不等,也可以測試一個串是否賦了值。有關(guān)串的操作符如下:
          str1 = str2      當(dāng)兩個串有相同內(nèi)容、長度時為真
          str1 != str2      當(dāng)串str1和str2不等時為真
          -n str1        當(dāng)串的長度大于0時為真(串非空)
          -z str1        當(dāng)串的長度為0時為真(空串)
          str1         當(dāng)串str1為非空時為真

        不但Shell程序可以使用test進(jìn)行條件判斷,test命令也可以獨(dú)立執(zhí)行,如:

          $str1=abcd
          $test $str1 = abcd
          $echo $?
          結(jié)果顯示:0

      與上例中第一行賦值語句中的等號不同,test命令中的等號兩邊必須要有空格。本例test命令共有3個參數(shù)。注意兩個串相等必須是長度和內(nèi)容都相等。

          $str1="abcd "
          $test "$str1" = abcd
          $echo $?
          結(jié)果顯示:1

        上面str1包含5個字符,其中最后一個為空格符。而test命令中的另一個串只有4個字符,所以兩串不等,test返回1。

        不帶任何操作符和使用-n操作符測試一個串結(jié)果是一樣的,例如:

          $str1=abce
          $test $str1
          $echo $?
          結(jié)果顯示:0    
          $test -n $str1
          $echo $?
          結(jié)果顯示:0

        但是,上面兩條命令也有一點(diǎn)差別,反映出了使用test命令潛在的問題,請看下例:

          $str1="   "
          $test $str1
          $echo $?
          結(jié)果顯示:1
          $test -n "$str1"
          $echo $?
          結(jié)果顯示:0
          $test -n $str1
          結(jié)果顯示:test:argument expected

        上例中,第一次測試為假因為Shell在執(zhí)行命令行之前首先要進(jìn)行變量替換,即把$str1換成空格,然后shell又將命令行上的空格刪除,故test命令測試到的為空串。而在第二次測試中,變量替換后空格位于括號內(nèi),故不會被刪除,test測試到的是一個包含空格的串,在第三次測試中,shell把空格刪除,只把-n傳個test命令,所以顯示參數(shù)錯。

      2>測試兩個整數(shù)之間關(guān)系

        test命令與expr命令一樣,也可以把字符轉(zhuǎn)變成整數(shù),然后對其操作。test命令對兩個數(shù)進(jìn)行比較,使用的操作符如下:

          int1 -eq int2    兩數(shù)相等為真
          int1 -ne int2    兩數(shù)不等為真
          int1 -gt int2    int1大于int2為真
          int1 -ge int2    int1大于等于int2為真
          int1 -lt int2    int1小于int2為真
          int1 -le int2    int1小于等于int2為真

        下面的例子反映了字符串比較與數(shù)字比較的不同:

          $str1=1234
          $str2=01234
          $test $str1 = $str2
          $echo $?
          結(jié)果顯示:1
          $test $str1 -eq $str2
          $echo $?
          結(jié)果顯示:0

      3>有關(guān)文件的測試

        使用test進(jìn)行的第三類測試是測試文件的狀態(tài),用戶可以測試文件是否存在,是否可寫以及其他文件屬性。下面是文件測試時使用的選項。注意只有文件存在時,才有可能為真。

        -r file     用戶可讀為真
        -w file     用戶可寫為真
        -x file     用戶可執(zhí)行為真
        -f file     文件為正規(guī)文件為真
        -d file     文件為目錄為真
        -c file     文件為字符特殊文件為真
        -b file     文件為塊特殊文件為真
        -s file     文件大小非0時為真
        -t file     當(dāng)文件描述符(默認(rèn)為1)指定的設(shè)備為終端時為真
      4>復(fù)雜的條件測試(and 、or 、not)
        -a         與
        -o        或
        !        非
        就是組合條件了,任何高級語言中都有的(NOT 、AND 、OR),例如:
          $test -r em.null -a -s em.null
          $echo $?
          結(jié)果顯示:1
          說明了em.null并不是可讀并且非空的文件

      5>另一種執(zhí)行test的方法

        bsh中還有另一種執(zhí)行test命令的方法,就是把測試條件放到一對[ ]中,例如:
          $int1=4
          $[ $int1 -gt 2 ]
          $echo $?
          結(jié)果顯示:0
      要注意在[ 的后面和 ]符號的前面要有一個空格。
        下面我們用test命令寫個簡單但比較完善的程序:

          #-- 備份程序
        
          #-- 檢查參數(shù)
          if [ $# -ne 1 ]
          then

            echo "請在程序名后面指出要備份文件所在目錄!"
            exit 1
          fi
          #-- 檢查目錄名是否有效
          if [ !-d "$1" ]
          then
            echo "$1 不是一個目錄!"
            exit 2
          fi
          cd $1
          ls -a | cpio -o >/dev/mnt0
          if [ $? -eq 0 ]
          then
            rm *
          else
            echo "cpio執(zhí)行不成功!備份失敗..."
            exit 3
          fi

      6>空命令

        在Bsh中用 : 代表空命令,就是充個數(shù),什么都不做

      7>嵌套if語句和elif結(jié)構(gòu)

        檢查條件1
        A:當(dāng)條件1為真,則執(zhí)行一部分操作
        B:若條件1為假,檢查條件2
          1)若條件2為真,執(zhí)行另外一部分操作
          2)若條件2為假,檢查條件3
          3)若條件3為真,執(zhí)行其他一部分操作
        語法如下:
          if command
          then
            command
          else
            if command
            then
              command
            else
              if command
              then
                command
              fi
            fi
          fi

      8>elif語句

        嵌套if語句有時會給用戶帶來混亂,特別是什么時候fi語句很難判斷。因此Bourne Shell又提供了elif語句。elif是else-if的縮寫,它表示是if語句的繼續(xù)。格式為:

          if command
          then
            command
          elif command
          then
            command
          elif command
          then
            command
          fi

        上面介紹的嵌套if語句和elif語句完成相同的功能,用戶可以根據(jù)自己的喜好選擇一種使用。

      9>case語句

        前面說的elif語句替代if-then-else語句,但有時在編程時還會遇到對同一變量進(jìn)行多次的測試,該情況可以用多個elif語句實(shí)現(xiàn),但還有一種更簡單的方法就是用case語句。

        case語句不但取代了多個elif和then語句,還可以用變量值對多個模式進(jìn)行匹配,當(dāng)某個模式與變量值匹配后,其后的一系列命令將被執(zhí)行,下面是case語句使用的語句。

        case value in
         pattem 1)
          command
          command;;
         pattem 2)
          command
          command;;
         ....
         pattem)
          command;
        esac

        case語句只執(zhí)行其中的一組命令,當(dāng)變量值與多個模式相匹配時,只有第一個匹配的模式對應(yīng)的命令被執(zhí)行。";;"表示該模式對應(yīng)的命令部分程序。

        通過學(xué)習(xí)下面的read語句,我們們再舉例子說明case語句的用法。

      10>read語句

        Shell程序不但可以通過命令行參數(shù)得到輸入數(shù)據(jù),還可以使用read命令提示用戶輸入數(shù)據(jù),其語法格式為:

        read var1 var2... ...varn

      當(dāng)Bsh遇到一個read語句時,在標(biāo)準(zhǔn)輸入文件中讀取數(shù)據(jù)直到一個換行符。此時Shell在解釋輸入行時,不進(jìn)行文件名或變量的替換,只是簡單地刪除多余的空格。然后Shell將輸入行的第一個字的內(nèi)容給變量1,第二個給變量2,直到所有變量都賦上值或是輸入行為空。若輸入行中字的個數(shù)超過變量個數(shù),Shell將把輸入行中剩余的所有字的內(nèi)容都賦給最后一個變量。當(dāng)變量個數(shù)多于輸入行字的個數(shù)時候,多于的變量將賦一個空值。輸入行的每一個字是由空格分隔的一個字母和數(shù)字組成的字符串。

        $read var1 var2 var3
          輸入:Hello my friend
        
        $echo $var1 $var2 $var3
          結(jié)果顯示:Hello my friend
        $echo $var2
          結(jié)果顯示:my

      下面用個read和case的例子結(jié)束本部分的學(xué)習(xí):

        #--交互式備份,恢復(fù)程序
        echo "輸入要備份文件所在目錄:\c"
        read WORKDIR
        if [ !-d $WORKDIR ]
        then
          echo "Sorry,$WORKDIR is not a directory"
          exit 1
        fi
        cd $WORKDIR
        echo "輸入選擇:"
        echo _
        echo "1.恢復(fù)到 $WORKDIR"
        echo "2.備份 $WORKDIR"
        echo "0.退出"
        echo
        echo "\c"
        read CHOICE
        case "$CHOICE" in
         1)echo "恢復(fù)中... ..."
          cpio -i < /dev/mnt0;;
         2)echo "備份中... ..."
          ls | cpio -o > /dev/mnt0;;
         0)exit 1
         *)exit 1
        esac
        if [ $? -ne 0 ]
        then
         echo "程序運(yùn)行中出現(xiàn)錯誤!"
        else
         echo "操作成功!"
        fi  
       
        在上面代碼中,"*"定義了其他模式下不匹配時的默認(rèn)操作。

      循環(huán)語句

        前面介紹的程序和所學(xué)的語句都是從頭到尾成一條主線下來,或是成分支結(jié)構(gòu),在日常管理UNIX的過程中,經(jīng)常要重復(fù)的做一些操作,處理批量的問題,這就涉及到了循環(huán)結(jié)構(gòu),同高級語言相似,UNIX的Shell也提供了強(qiáng)大的循環(huán)處理語句。

        Bsh語言中有三種循環(huán)語句-while循環(huán)、until循環(huán)、for循環(huán),下面通過具體的例子分別介紹這三種結(jié)構(gòu)。

        While循環(huán)

        在while循環(huán)語句中,當(dāng)某一條件為真時,執(zhí)行指定的命令。語句的結(jié)構(gòu)如下:

      while command
      do
        command
        command
        … …
      done

      示例代碼如下:

      #測試while循環(huán)小程序

      x_t=1
        while [ $x_t -lt 5 ]
        do
           mm=` expr $x_t \* $int `  #注意"\"的作用
           echo "$mm"
           x_t=` expr $x_t + 1 `   #注意expr的用法
        done
        echo "THE WHILE IS END!\n"

      程序的執(zhí)行結(jié)果如下:
      1
      4
      9
      16
      THE WHILE IS END

        在上述程序中,當(dāng)變量x_t的值小于5的時候,執(zhí)行while循環(huán)中的語句。在第五次循環(huán)時, [ $x_t-lt5]命令返回非零值,于是程序執(zhí)行done后面的代碼。
      現(xiàn)在利用while循環(huán),可以改進(jìn)我們早些時候用的備份數(shù)據(jù)的例子,當(dāng)用戶指定的目錄備份完畢后,使用while循環(huán)使程序執(zhí)行一次可以備份多個用戶指定的目錄。代碼如下:

      echo "歡迎使用備份小程序"

        ANS=Y
        while [ $ANS = Y -o $ANS = y ]
        do
          echo _
          #讀目錄名
          echo "輸入要備份的目錄名:\c"
          read DIR
          if [ ! -d $DIR ]
          then
              echo "$DIR不是一個目錄!"
              exit 1
          fi
          cd $DIR
          echo "請選擇:"
          echo _
          echo "1 恢復(fù)數(shù)據(jù)到 $DIR"
          echo "2 備份$DIR的數(shù)據(jù)"
          echo
          echo "請選擇:\c"
          read CHOICE
          case "$CHOICE" in
             1) echo "恢復(fù)中… …"
              cpio -i        2) echo "備份中… …"
              cpio -o >/dev/rmt0;;
             *) echo "選擇無效"
          esac
          if [ $? -ne 0 ]
          then
             echo "cpio執(zhí)行過程中出現(xiàn)問題"
             exit 2
          fi
          echo "繼續(xù)別的目錄嗎?(Y/y)\c"
          read ANS
        done

        在程序開始,我們給變量ANS符值為Y,根據(jù)whlie的判斷條件,程序進(jìn)入while循環(huán),執(zhí)行do-done中的語句,每次循環(huán)都要求用戶輸入ANS的值用來判斷是否進(jìn)行下次重復(fù)執(zhí)行do-done中的語句。如果用戶輸入的條件不滿足while語句條件,循環(huán)結(jié)束,程序執(zhí)行done后面的語句。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多