天天看點

shell腳本中一些特殊符号

在shell中常用的特殊符号羅列如下: 

# ;   ;; . , / \\ 'string'| !   $   ${}   $? $$   $* 

\"string\"* **   ? : ^ $#   $@ `command`{}   [] [[]] ()   (()) 

||   && {xx,yy,zz,...}~   ~+   ~-   &   \\<...\\>   + - %=   ==   != 

# 井号 (comments) 

這幾乎是個滿場都有的符号,除了先前已經提過的\"第一行\" 

#!/bin/bash 

井号也常出現在一行的開頭,或者位于完整指令之後,這類情況表示符号後面的是注解文字,不會被執行。 

# This line is comments. 

echo \"a = $a\" # a = 0 

由于這個特性,當臨時不想執行某行指令時,隻需在該行開頭加上 # 就行了。這常用在撰寫過程中。 

#echo \"a = $a\" # a = 0 

如果被用在指令中,或者引号雙引号包覆的話,或者在倒斜線的後面,那他就變成一般符号,不具上述的特殊功能。 

~ 帳戶的 home 目錄 

算是個常見的符号,代表使用者的 home 目錄:cd ~;也可以直接在符号後加上某帳戶的名稱:cd ~user或者當成是路徑的一部份:~/bin 

~+ 目前的工作目錄,這個符号代表目前的工作目錄,她和内建指令 pwd的作用是相同的。 

# echo ~+/var/log 

~- 上次的工作目錄,這個符号代表上次的工作目錄。 

# echo ~-/etc/httpd/logs 

; 分号 (Command separator) 

在 shell 中,擔任\"連續指令\"功能的符号就是\"分号\"。譬如以下的例子:cd ~/backup ; mkdir startup ;cp ~/.* startup/. 

;; 連續分号 (Terminator) 

專用在 case 的選項,擔任 Terminator 的角色。 

case \"$fop\" inhelp) echo \"Usage: Command -help -version filename\";;version) echo \"version 0.1\" ;;esac 

. 逗号 (dot,就是“點”) 

在 shell 中,使用者應該都清楚,一個 dot 代表目前目錄,兩個 dot 代表上層目錄。 

CDPATH=.:~:/home:/home/web:/var:/usr/local 

在上行 CDPATH 的設定中,等号後的 dot 代表的就是目前目錄的意思。 

如果檔案名稱以 dot 開頭,該檔案就屬特殊檔案,用 ls 指令必須加上 -a 選項才會顯示。除此之外,在 regularexpression 中,一個 dot 代表比對一個字元。 

'string' 單引号 (single quote) 

被單引号用包覆的内容,将被視為單一字串。在引号内的代表變數的$符号,沒有作用,也就是說,他被視為一般符号處理,防止任何變量替換。 

heyyou=homeecho '$heyyou' # We get $heyyou 

\"string\" 雙引号 (double quote) 

被雙引号用包覆的内容,将被視為單一字串。它防止通配符擴充,但允許變量擴充。這點與單引數的處理方式不同。 

heyyou=homeecho \"$heyyou\" # We get home 

`command` 倒引号 (backticks) 

在前面的單雙引号,包覆的是字串,但如果該字串是一列指令列,會怎樣?答案是不會執行。要處理這種情況,我們得用倒單引号來做。 

fdv=`date +%F`echo \"Today $fdv\" 

在倒引号内的 date +%F 會被視為指令,執行的結果會帶入 fdv 變數中。 

, 逗點 (comma,标點中的逗号) 

這個符号常運用在運算當中當做\"區隔\"用途。如下例 

#!/bin/bashlet \"t1 = ((a = 5 + 3, b = 7 - 1, c = 15 / 3))\"echo \"t1= $t1, a = $a, b = $b\" 

/ 斜線 (forward slash) 

在路徑表示時,代表目錄。 

cd /etc/rc.dcd ../..cd / 

通常單一的 / 代表 root 根目錄的意思;在四則運算中,代表除法的符号。 

let \"num1 = ((a = 10 / 2, b = 25 / 5))\" 

\\ 倒斜線 

在互動模式下的escape 字元,有幾個作用;放在指令前,有取消 aliases的作用;放在特殊符号前,則該特殊符号的作用消失;放在指令的最末端,表示指令連接配接下一行。 

# type rmrm is aliased to `rm -i'# \\rm ./*.log 

上例,我在 rm 指令前加上 escape 字元,作用是暫時取消别名的功能,将 rm 指令還原。 

# bkdir=/home# echo \"Backup dir, \\$bkdir = $bkdir\"Backup dir,$bkdir = /home 

上例 echo 内的 \\$bkdir,escape 将 $ 變數的功能取消了,是以,會輸出 $bkdir,而第二個 $bkdir則會輸出變數的内容 /home。 

| 管道 (pipeline) 

pipeline 是 UNIX 系統,基礎且重要的觀念。連結上個指令的标準輸出,做為下個指令的标準輸入。 

who | wc -l 

善用這個觀念,對精簡 script 有相當的幫助。 

! 驚歎号(negate or reverse) 

通常它代表反邏輯的作用,譬如條件偵測中,用 != 來代表\"不等于\" 

if [ \"$?\" != 0 ]thenecho \"Executes error\"exit 1fi 

在規則表達式中她擔任 \"反邏輯\" 的角色 

ls a[!0-9] 

上例,代表顯示除了a0, a1 .... a9 這幾個檔案的其他檔案。 

: 冒号 

在 bash 中,這是一個内建指令:\"什麼事都不幹\",但傳回狀态值 0。 

echo $? # 回應為 0 

: > f.

上面這一行,相當于cat/dev/null>f.

。不僅寫法簡短了,而且執行效率也好上許多。 

有時,也會出現以下這類的用法 

: ${HOSTNAME?} ${USER?} ${MAIL?} 

這行的作用是,檢查這些環境變數是否已設定,沒有設定的将會以标準錯誤顯示錯誤訊息。像這種檢查如果使用類似 test 或 if這類的做法,基本上也可以處理,但都比不上上例的簡潔與效率。 

? 問号 (wild card) 

在檔案名擴充(Filename expansion)上扮演的角色是比對一個任意的字元,但不包含 null 字元。 

# ls a?a1 

善用她的特點,可以做比較精确的檔名比對。 

* 星号 (wild card) 

相當常用的符号。在檔案名擴充(Filename expansion)上,她用來代表任何字元,包含 null 字元。 

# ls a*a a1 access_log 

在運算時,它則代表 \"乘法\"。 

let \"fmult=2*3\" 

除了内建指令 let,還有一個關于運算的指令expr,星号在這裡也擔任\"乘法\"的角色。不過在使用上得小心,他的前面必須加上escape 字元。 

** 次方運算 

兩個星号在運算時代表 \"次方\" 的意思。 

let \"sus=2**3\"echo \"sus = $sus\" # sus = 8 

$ 錢号(dollar sign) 

變量替換(Variable Substitution)的代表符号。 

vrs=123echo \"vrs = $vrs\" # vrs = 123 

另外,在 Regular Expressions 裡被定義為 \"行\" 的最末端 (end-of-line)。這個常用在grep、sed、awk 以及 vim(vi) 當中。 

${} 變量的正規表達式 

bash 對 ${} 定義了不少用法。以下是取自線上說明的表列 

   ${parameter:-word}   ${parameter:=word}   ${parameter:?word}   ${parameter:+word}   ${parameterffset}   ${parameterffset:length}   ${!prefix*}   ${#parameter}   ${parameter#word}   ${parameter##word}   ${parameter%word}   ${parameter%%word}   ${parameter/pattern/string}   ${parameter//pattern/string} 

$* 

$* 引用script的執行引用變量,引用參數的算法與一般指令相同,指令本身為0,其後為1,然後依此類推。引用變量的代表方式如下: 

$0, $1, $2, $3, $4, $5, $6, $7, $8, $9, ${10}, ${11}..... 

個位數的,可直接使用數字,但兩位數以上,則必須使用 {} 符号來包覆。 

$* 則是代表所有引用變量的符号。使用時,得視情況加上雙引号。 

echo \"$*\" 

還有一個與 $* 具有相同作用的符号,但效用與處理方式略為不同的符号。 

$@ 

$@ 與 $* 具有相同作用的符号,不過她們兩者有一個不同點。 

符号 $* 将所有的引用變量視為一個整體。但符号 $@ 則仍舊保留每個引用變量的區段觀念。 

$# 

這也是與引用變量相關的符号,她的作用是告訴你,引用變量的總數量是多少。 

echo \"$#\" 

$? 狀态值 (status variable) 

一般來說,UNIX(linux) 系統的程序以執行系統調用exit()來結束的。這個回傳值就是status值。回傳給父程序,用來檢查子程序的執行狀态。 

一般指令程式倘若執行成功,其回傳值為 0;失敗為 1。 

tar cvfz dfbackup.tar.gz /home/user > /dev/nullecho\"$?\"

由于程序的ID是唯一的,是以在同一個時間,不可能有重複性的PID。有時,script會需要産生臨時檔案,用來存放必要的資料。而此script亦有可能在同一時間被使用者們使用。在這種情況