天天看點

SHELL腳本-第二課回顧基礎知識參考資料

SHELL腳本-第二課

  • 回顧
  • 基礎知識
    • 特殊字元
  • 參考資料

回顧

  1. shell腳本程式設計的不适用場景的列舉;1
  2. 簡單的shell腳本展示;
  3. 解釋器說明及注意事項;
  4. 腳本的運作方式。

基礎知識

在此,我們将對一些特殊字元,變量命名及常見使用方式做一些介紹,以便你做基本的了解。首先,我們來看看看有哪些特殊的字元值得注意。

特殊字元

腳本中常常會出現一些特殊的字元,他們都表示一些特定的含義,我們接下來對它們做一一的介紹。

  1. #

    :以一個#開頭的行 (#!是例外) 是注釋行。例如:
  2. ;

    :【指令分割符】用分割符允許在同一行裡有兩個或更多的指令。例如:
    echo hello; echo there
    if [ -x "$filename" ]; then    # 注意:"if" and "then"需要分隔符
                                   # 思考一下這是為什麼?
      echo "File $filename exists."; cp $filename $filename.bak
    else
      echo "File $filename not found."; touch $filename
    fi; echo "File test complete."
               
  3. ;;

    :case語句分支的結束符[雙分号]。例如:
    case "$variable" in
    abc)  echo "\$variable = abc" ;;
    xyz)  echo "\$variable = xyz" ;;
    esac
               
  4. '

    :'STRING’能引用STRING裡的所有字元(包括特殊字元也會被原樣引用)。這是一個比使用雙引号(“)更強的引用。 例如:
    #! /bin/bash
    hello="A B C D"
    echo $hello
    echo "$hello"
    echo '$hello'
               
    運作結果如下所示:

    $bash string

    A B C D

    A B C D

    $hello

    從運作結果可以看出,在單引号中的變量引用會被禁止,字元

    $

    會僅僅被認為是一個普通的字元,而不是變量的字首。
  5. "

    :"STRING"的引用會使STRING裡的特殊字元能夠被解釋。其中例子如上所示。
  6. .

    :等同于source。這是一個bash的内建指令。

    在這邊

    .

    符号可以在腳本中的作用類似于

    C

    語言中的

    #include

    ,可以直接調用

    #include

    中的變量以及函數。調用

    ./bbb

    腳本如下:
    # This is a data file loaded by a script.
    # Files of this type may contain variables, functions, etc.
    # It may be loaded with a 'source' or '.' command by a shell script.
     
    # Let's initialize some variables.
     
    variable1=22
    variable2=474
    variable3=5
    variable4=97
    
    message1="Hello, how are you?"
    message2="Enough for now. Goodbye."
     
    print_message ()
    {
    	#Echoes any message passed to it.	 
    	if [ -z "$1" ]
    	then
    	    return 1
    	    # Error, if argument missing.
    	fi
    	
    	echo	 
    	until [ -z "$1" ]
    	do
    	   # Step through arguments passed to function.
    	   echo -n "$1"
    	   # Echo args one at a time, suppressing line feeds.
    	   echo -n " "
    	   # Insert spaces between words.
    	   shift
    	   # Next one.
    	done  
    	 
    	echo	 
    	return 0
    }  
               
    接下來,通過另外一個腳本調用其中的變量以及函數。例如:
    #!/bin/bash
    . bbb    # Load a data file.
    echo "variable1 (from data-file) = $variable1"
    echo "variable3 (from data-file) = $variable3"
    
    let "sum = $variable2 + $variable4"
    echo "Sum of variable2 + variable4 (from data-file) = $sum"
    echo "message1 (from data-file) is \"$message1\""
    exit 0
               
    運作結果如下所示:

    $ sh kkk

    variable1 (from data-file) = 22

    variable3 (from data-file) = 5

    Sum of variable2 + variable4 (from data-file) = 571

    message1 (from data-file) is “Hello, how are you?”

    -n This

    -n

    -n is

    -n

    -n the

    -n

    -n message-print

    -n

    -n function

    -n

    -n in

    -n

    -n the

    -n

    -n data-file.

    -n

  7. ,

    :逗号操作符用于連接配接一連串的數學表達式。這一串的數學表達式每一個都被求值,但隻有最後一個被傳回。例如:
  8. \

    :用于單個字元的引用機制。

    \X

    "轉義"字元為

    X

  9. /

    :分隔一個檔案路徑的各個部分。例如:

    /home/bozo/projects/Makefile

  10. `:(由于這個符号比較特殊我就直接用這種方式表示了)将會重新配置設定一個指令甚至是多個指令的輸出;它會将指令的輸出如實地添加到另一個上下文中。例如:
    #!/bin/bash
    textfile_listing=`ls *`
    echo "$textfile_listing"
               
    運作結果如下所示(下面都是目前目錄下的檔案):

    $ sh commandchange

    bbb

    commandchange

    kkk

    string

  11. :

    :這個指令意思是空操作(即什麼操作也不做). 它一般被認為是和shell的内建指令true是一樣的。冒号":" 指令是Bash自身内建的, and its它的退出狀态碼是真(即0)。例如:
    if condition
    then :   # 什麼也不做的分支
    else
       take-some-action
    fi
               

    :

    的特殊使用方法如下所示:
    #!/bin/bash
     # 用10種不同的方法計數到11.
     n=1; echo -n "$n "
     
     let "n = $n + 1"   # let "n = n + 1"也可以.
     echo -n "$n "
      
     :$((n = $n + 1))
     #  ":"是需要的,
     #+ 否則Bash會嘗試把"$((n = $n + 1))"作為指令運作.
     echo -n "$n "
     
     (( n = n + 1 ))
     #  上面是更簡單的可行的辦法.
     echo -n "$n "
     
     n=$(($n + 1))
     echo -n "$n "
     
     : $[ n = $n + 1 ]
     #  ":"是需要的,
     #+ 否則Bash會嘗試把"$[ n = $n + 1 ]"作為指令運作.
     #  即使"n"被當作字元串來初始化也能工作.
     echo -n "$n "
     
     n=$[ $n + 1 ]
     #  即使"n"被當作字元串來初始化也能工作.
     #* 應避免這種使用這種結構,因為它是被廢棄并不可移植的.
     echo -n "$n "
     
     # 現在是C風格的增加操作.
     # 多謝Frank Wang指出這一點.
     
     let "n++"          # let "++n"也可以.
     echo -n "$n "
     
     (( n++ ))          # (( ++n )也可以.
     echo -n "$n "
     
     : $(( n++ ))       # : $(( ++n ))也可以.
     echo -n "$n "
     
     : $[ n++ ]         # : $[ ++n ]]也可以.
     echo -n "$n "
     echo
     
     exit 0
               
    運算結果如下所示:

    $ sh compoperater

    -n 1

    -n 2

    -n 3

    -n 4

    -n 5

    -n 6

    -n 7

    -n 8

    -n 9

    -n 10

    -n 11

  12. !

    :取反一個測試結果或退出狀态。
  13. *

    :星号(*)字元在用于比對檔案名擴充的一個通配符,它自動比對給定的目錄下的每一個檔案。 在計算時,星号

    *

    表示乘法運算符。兩個星号

    **

    表示求幂運算符。
  14. ?

    :字元?被用于檔案名擴充特性的檔案名表達式的單字元比對,同時也在擴充正規表達式中比對任意一個字元。
  15. $

    :變量替換 (引用一個變量的内容)。
    var1=5
    var2=23skidoo
    
    echo $var1     # 5
    echo $var2     # 23skidoo
               
  16. &

    :在背景運作作業。 一個後面跟一個

    &

    的指令會在背景運作。
  17. |

    :管道。把上一個指令的輸出傳給下一個指令,或是shell。這是連接配接指令的一種方法。
  18. $?

    :儲存退出碼值的變量. 變量$?儲存了一個指令,一個函數,或一個腳本的退出狀态碼的值。
  19. $*, $@

    :位置參數。
  20. ${}

    :參數替換。
  21. ()

    :指令組。一組由圓括号括起來的指令是新開一個子shell來執行的。因為是在子shell裡執行,在圓括号裡的變量不能被腳本的其他部分通路。因為父程序(即腳本程序)不能存取子程序(即子shell)建立的變量。例如:
    a=123
    ( a=321; )	       
    echo "a = $a"   # a = 123
    # 在圓括号裡的變量"a"實際上是一個局部變量,作用局域隻是在圓括号内用于數組始初化
               
  22. {}

    :這個結構也是一組指令代碼塊,事實上,它是匿名的函數。然而與一個函數所不同的,在代碼塊裡的變量仍然能被腳本後面的代碼通路。例如:
    1 #!/bin/bash
       2 # rpm-check.sh
       3 
       4 # 查詢一個rpm安裝包的描述,軟體清單,和是否它能夠被安裝.
       5 # 并把結果儲存到一個檔案中.
       6 # 
       7 # 這個腳本使用一個代碼塊來舉例說明。
       8 
       9 SUCCESS=0
      10 E_NOARGS=65
      11 
      12 if [ -z "$1" ]
      13 then
      14   echo "Usage: `basename $0` rpm-file"
      15   exit $E_NOARGS
      16 fi  
      17 
      18 { 
      19   echo
      20   echo "Archive Description:"
      21   rpm -qpi $1       # 查詢軟體包的描述.
      22   echo
      23   echo "Archive Listing:"
      24   rpm -qpl $1       # 查詢軟體包中的軟體清單.
      25   echo
      26   rpm -i --test $1  # 查詢該軟體包能否被安裝.
      27   if [ "$?" -eq $SUCCESS ]
      28   then
      29     echo "$1 can be installed."
      30   else
      31     echo "$1 cannot be installed."
      32   fi  
      33   echo
      34 } > "$1.test"       # 把代碼塊的所有輸出重定向到一個檔案中。
      35 
      36 echo "Results of rpm test in file $1.test"
      37 
      38 # 參考rpm的man手冊來了解上面所用的選項。
      39 
      40 exit 0
               
  23. > &> >& >> <

    • sciptname >filename

      :重定向scriptname的輸出到檔案filename中去。如果檔案filename存在則将會被覆寫。
    • command &>filename

      :會重定向指令command标準輸出(stdout)和标準錯誤(stderr)到檔案filename中。
    • command >&2

      :把指令command的标準輸出(stdout)重定向到标準錯誤(stderr)。
    • scriptname >>filename

      :appends把腳本scriptname的輸出追加到檔案filename。如果filename不存在,則它會被建立。
  24. -

    :先前的工作目錄。 指令

    cd -

    可以回到原來的工作目錄.它使用了

    $OLDPWD

    環境變量。
  25. ~+

    :目前工作目錄。它與外部變量

    $PWD

    是一緻的。
  26. ~-

    :先前的工作目錄。它與外部變量

    $OLDPWD

    是一緻的。

以上即為常見的特殊字元,可更有利于運用特殊字元來簡化腳本程式設計。

參考資料

  1. SHELL腳本-第一課 ↩︎

繼續閱讀