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

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

    • 分享

      shell腳本語法

       day_day__UP 2015-05-07

       Shell腳本語法

      1. 條件測(cè)試:test

      命令test[可以測(cè)試一個(gè)條件是否成立,如果測(cè)試結(jié)果為真,則該命令的Exit Status為0,如果測(cè)試結(jié)果為假,則命令的Exit Status為1(注意與C語言的邏輯表示正好相反)。例如測(cè)試兩個(gè)數(shù)的大小關(guān)系:

      $ VAR=2
      $ test $VAR -gt 1
      $ echo $?
      0
      $ test $VAR -gt 3
      $ echo $?
      1
      $ [ $VAR -gt 3 ]
      $ echo $?
      1

      雖然看起來很奇怪,但左方括號(hào)[確實(shí)是一個(gè)命令的名字,傳給命令的各參數(shù)之間應(yīng)該用空格隔開,比如,$VAR、-gt3、][命令的四個(gè)參數(shù),它們之間必須用空格隔開。命令test[的參數(shù)形式是相同的,只不過test命令不需要]參數(shù)。以[命令為例,常見的測(cè)試命令如下表所示:

      表 31.2. 測(cè)試命令

      [ -d DIR ]如果DIR存在并且是一個(gè)目錄則為真
      [ -f FILE ]如果FILE存在且是一個(gè)普通文件則為真
      [ -z STRING ]如果STRING的長(zhǎng)度為零則為真
      [ -n STRING ]如果STRING的長(zhǎng)度非零則為真
      [ STRING1 = STRING2 ]如果兩個(gè)字符串相同則為真
      [ STRING1 != STRING2 ]如果字符串不相同則為真
      [ ARG1 OP ARG2 ]ARG1ARG2應(yīng)該是整數(shù)或者取值為整數(shù)的變量,OP-eq(等于)-ne(不等于)-lt(小于)-le(小于等于)-gt(大于)-ge(大于等于)之中的一個(gè)

      和C語言類似,測(cè)試條件之間還可以做與、或、非邏輯運(yùn)算:

      表 31.3. 帶與、或、非的測(cè)試命令

      [ ! EXPR ]EXPR可以是上表中的任意一種測(cè)試條件,!表示邏輯反
      [ EXPR1 -a EXPR2 ]EXPR1EXPR2可以是上表中的任意一種測(cè)試條件,-a表示邏輯與
      [ EXPR1 -o EXPR2 ]EXPR1EXPR2可以是上表中的任意一種測(cè)試條件,-o表示邏輯或

      例如:

      $ VAR=abc
      $ [ -d Desktop -a $VAR = 'abc' ]
      $ echo $?
      0

      注意,如果上例中的$VAR變量事先沒有定義,則被Shell展開為空字符串,會(huì)造成測(cè)試條件的語法錯(cuò)誤(展開為[ -d Desktop -a = 'abc' ]),作為一種好的Shell編程習(xí)慣,應(yīng)該總是把變量取值放在雙引號(hào)之中(展開為[ -d Desktop -a "" = 'abc' ]):

      $ unset VAR
      $ [ -d Desktop -a $VAR = 'abc' ]
      bash: [: too many arguments
      $ [ -d Desktop -a "$VAR" = 'abc' ]
      $ echo $?
      1

      2. if/then/elif/else/fi

      和C語言類似,在Shell中用ifthen、elif、elsefi這幾條命令實(shí)現(xiàn)分支控制。這種流程控制語句本質(zhì)上也是由若干條Shell命令組成的,例如先前講過的

      if [ -f ~/.bashrc ]; then
          . ~/.bashrc
      fi

      其實(shí)是三條命令,if [ -f ~/.bashrc ]是第一條,then . ~/.bashrc是第二條,fi是第三條。如果兩條命令寫在同一行則需要用;號(hào)隔開,一行只寫一條命令就不需要寫;號(hào)了,另外,then后面有換行,但這條命令沒寫完,Shell會(huì)自動(dòng)續(xù)行,把下一行接在then后面當(dāng)作一條命令處理。和[命令一樣,要注意命令和各參數(shù)之間必須用空格隔開。if命令的參數(shù)組成一條子命令,如果該子命令的Exit Status為0(表示真),則執(zhí)行then后面的子命令,如果Exit Status非0(表示假),則執(zhí)行elif、else或者fi后面的子命令。if后面的子命令通常是測(cè)試命令,但也可以是其它命令。Shell腳本沒有{}括號(hào),所以用fi表示if語句塊的結(jié)束。見下例:

      #! /bin/sh
      
      if [ -f /bin/bash ]
      then echo "/bin/bash is a file"
      else echo "/bin/bash is NOT a file"
      fi
      if :; then echo "always true"; fi

      :是一個(gè)特殊的命令,稱為空命令,該命令不做任何事,但Exit Status總是真。此外,也可以執(zhí)行/bin/true/bin/false得到真或假的Exit Status。再看一個(gè)例子:

      #! /bin/sh
      
      echo "Is it morning? Please answer yes or no."
      read YES_OR_NO
      if [ "$YES_OR_NO" = "yes" ]; then
        echo "Good morning!"
      elif [ "$YES_OR_NO" = "no" ]; then
        echo "Good afternoon!"
      else
        echo "Sorry, $YES_OR_NO not recognized. Enter yes or no."
        exit 1
      fi
      exit 0

      上例中的read命令的作用是等待用戶輸入一行字符串,將該字符串存到一個(gè)Shell變量中。

      此外,Shell還提供了&&和||語法,和C語言類似,具有Short-circuit特性,很多Shell腳本喜歡寫成這樣:

      test "$(whoami)" != 'root' && (echo you are using a non-privileged account; exit 1)

      &&相當(dāng)于“if...then...”,而||相當(dāng)于“if not...then...”。&&和||用于連接兩個(gè)命令,而上面講的-a-o僅用于在測(cè)試表達(dá)式中連接兩個(gè)測(cè)試條件,要注意它們的區(qū)別,例如,

      test "$VAR" -gt 1 -a "$VAR" -lt 3

      和以下寫法是等價(jià)的

      test "$VAR" -gt 1 && test "$VAR" -lt 3

      3. case/esac

      case命令可類比C語言的switch/case語句,esac表示case語句塊的結(jié)束。C語言的case只能匹配整型或字符型常量表達(dá)式,而Shell腳本的case可以匹配字符串和Wildcard,每個(gè)匹配分支可以有若干條命令,末尾必須以;;結(jié)束,執(zhí)行時(shí)找到第一個(gè)匹配的分支并執(zhí)行相應(yīng)的命令,然后直接跳到esac之后,不需要像C語言一樣用break跳出。

      #! /bin/sh
      
      echo "Is it morning? Please answer yes or no."
      read YES_OR_NO
      case "$YES_OR_NO" in
      yes|y|Yes|YES)
        echo "Good Morning!";;
      [nN]*)
        echo "Good Afternoon!";;
      *)
        echo "Sorry, $YES_OR_NO not recognized. Enter yes or no."
        exit 1;;
      esac
      exit 0

      使用case語句的例子可以在系統(tǒng)服務(wù)的腳本目錄/etc/init.d中找到。這個(gè)目錄下的腳本大多具有這種形式(以/etc/apache2為例):

      case $1 in
      	start)
      		...
      	;;
      	stop)
      		...
      	;;
      	reload | force-reload)
      		...
      	;;
      	restart)
      	...
      	*)
      		log_success_msg "Usage: /etc/init.d/apache2 {start|stop|restart|reload|force-reload|start-htcacheclean|stop-htcacheclean}"
      		exit 1
      	;;
      esac

      啟動(dòng)apache2服務(wù)的命令是

      $ sudo /etc/init.d/apache2 start

      $1是一個(gè)特殊變量,在執(zhí)行腳本時(shí)自動(dòng)取值為第一個(gè)命令行參數(shù),也就是start,所以進(jìn)入start)分支執(zhí)行相關(guān)的命令。同理,命令行參數(shù)指定為stop、reloadrestart可以進(jìn)入其它分支執(zhí)行停止服務(wù)、重新加載配置文件或重新啟動(dòng)服務(wù)的相關(guān)命令。

      4. for/do/done

      Shell腳本的for循環(huán)結(jié)構(gòu)和C語言很不一樣,它類似于某些編程語言的foreach循環(huán)。例如:

      #! /bin/sh
      
      for FRUIT in apple banana pear; do
        echo "I like $FRUIT"
      done

      FRUIT是一個(gè)循環(huán)變量,第一次循環(huán)$FRUIT的取值是apple,第二次取值是banana,第三次取值是pear。再比如,要將當(dāng)前目錄下的chap0chap1、chap2等文件名改為chap0~、chap1~、chap2~等(按慣例,末尾有~字符的文件名表示臨時(shí)文件),這個(gè)命令可以這樣寫:

      $ for FILENAME in chap?; do mv $FILENAME $FILENAME~; done

      也可以這樣寫:

      $ for FILENAME in `ls chap?`; do mv $FILENAME $FILENAME~; done

      5. while/do/done

      while的用法和C語言類似。比如一個(gè)驗(yàn)證密碼的腳本:

      #! /bin/sh
      
      echo "Enter password:"
      read TRY
      while [ "$TRY" != "secret" ]; do
        echo "Sorry, try again"
        read TRY
      done

      下面的例子通過算術(shù)運(yùn)算控制循環(huán)的次數(shù):

      #! /bin/sh
      
      COUNTER=1
      while [ "$COUNTER" -lt 10 ]; do
        echo "Here we go again"
        COUNTER=$(($COUNTER+1))
      done

      Shell還有until循環(huán),類似C語言的do...while循環(huán)。本章從略。

      習(xí)題

      1、把上面驗(yàn)證密碼的程序修改一下,如果用戶輸錯(cuò)五次密碼就報(bào)錯(cuò)退出。

      6. 位置參數(shù)和特殊變量

      有很多特殊變量是被Shell自動(dòng)賦值的,我們已經(jīng)遇到了$?$1,現(xiàn)在總結(jié)一下:

      表 31.4. 常用的位置參數(shù)和特殊變量

      $0相當(dāng)于C語言main函數(shù)的argv[0]
      $1、$2...這些稱為位置參數(shù)(Positional Parameter),相當(dāng)于C語言main函數(shù)的argv[1]、argv[2]...
      $#相當(dāng)于C語言main函數(shù)的argc - 1,注意這里的#后面不表示注釋
      $@表示參數(shù)列表"$1" "$2" ...,例如可以用在for循環(huán)中的in后面。
      $?上一條命令的Exit Status
      $$當(dāng)前Shell的進(jìn)程號(hào)

      位置參數(shù)可以用shift命令左移。比如shift 3表示原來的$4現(xiàn)在變成$1,原來的$5現(xiàn)在變成$2等等,原來的$1$2、$3丟棄,$0不移動(dòng)。不帶參數(shù)的shift命令相當(dāng)于shift 1。例如:

      #! /bin/sh
      
      echo "The program $0 is now running"
      echo "The first parameter is $1"
      echo "The second parameter is $2"
      echo "The parameter list is $@"
      shift
      echo "The first parameter is $1"
      echo "The second parameter is $2"
      echo "The parameter list is $@"

      7. 函數(shù)

      和C語言類似,Shell中也有函數(shù)的概念,但是函數(shù)定義中沒有返回值也沒有參數(shù)列表。例如:

      #! /bin/sh
      
      foo(){ echo "Function foo is called";}
      echo "-=start=-"
      foo
      echo "-=end=-"

      注意函數(shù)體的左花括號(hào){和后面的命令之間必須有空格或換行,如果將最后一條命令和右花括號(hào)}寫在同一行,命令末尾必須有;號(hào)。

      在定義foo()函數(shù)時(shí)并不執(zhí)行函數(shù)體中的命令,就像定義變量一樣,只是給foo這個(gè)名字一個(gè)定義,到后面調(diào)用foo函數(shù)的時(shí)候(注意Shell中的函數(shù)調(diào)用不寫括號(hào))才執(zhí)行函數(shù)體中的命令。Shell腳本中的函數(shù)必須先定義后調(diào)用,一般把函數(shù)定義都寫在腳本的前面,把函數(shù)調(diào)用和其它命令寫在腳本的最后(類似C語言中的main函數(shù),這才是整個(gè)腳本實(shí)際開始執(zhí)行命令的地方)。

      Shell函數(shù)沒有參數(shù)列表并不表示不能傳參數(shù),事實(shí)上,函數(shù)就像是迷你腳本,調(diào)用函數(shù)時(shí)可以傳任意個(gè)參數(shù),在函數(shù)內(nèi)同樣是用$0$1、$2等變量來提取參數(shù),函數(shù)中的位置參數(shù)相當(dāng)于函數(shù)的局部變量,改變這些變量并不會(huì)影響函數(shù)外面的$0、$1$2等變量。函數(shù)中可以用return命令返回,如果return后面跟一個(gè)數(shù)字則表示函數(shù)的Exit Status。

      下面這個(gè)腳本可以一次創(chuàng)建多個(gè)目錄,各目錄名通過命令行參數(shù)傳入,腳本逐個(gè)測(cè)試各目錄是否存在,如果目錄不存在,首先打印信息然后試著創(chuàng)建該目錄。

      #! /bin/sh
      
      is_directory()
      {
        DIR_NAME=$1
        if [ ! -d $DIR_NAME ]; then
          return 1
        else
          return 0
        fi
      }
      
      for DIR in "$@"; do
        if is_directory "$DIR"
        then :
        else
          echo "$DIR doesn't exist. Creating it now..."
          mkdir $DIR > /dev/null 2>&1
          if [ $? -ne 0 ]; then
            echo "Cannot create directory $DIR"
            exit 1
          fi
        fi
      done

      注意is_directory()返回0表示真返回1表示假。

       

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

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多