shell中有兩類字元,一類是普通字元,在Shell中除了本身的字面意思外沒有其他特殊意義,即普通純文字;另一類即元字元,是Shell的保留字元,在Shell中有着特殊的含義。
一、轉義
轉義是指使用轉義符引用單個字元,進而使其表達單純的字元的字面含義。Shell中的轉義符是反斜杠"\",使用轉義符的目的是使轉義符後面的字元單純地作為字元出現,而不解釋其特殊的含義。
#試圖列印"$Dollar"字元串的錯誤示範
[root@Cfhost-170820-UCNK ~]# echo $Dollar
#此處列印為空,因為Shell嘗試列印出變量Dollar的值,但是這個變量并沒有聲明,是以列印出空行
#使用轉義字元轉義$字元
[root@Cfhost-170820-UCNK ~]# echo \$Dollar
$Dollar
#更多例子
#列印乘号。如果不用轉義符轉義*号,則*号會作為一般的通配符使用,結果是将工作目錄中的所有目錄和檔案名替換它
[root@Cfhost-170820-UCNK ~]# echo 8 \* 8 =64
8 * 8 =64
[root@Cfhost-170820-UCNK ~]# echo john\'s cat
john's cat
在上面的示例中,指令的輸出将會是空字元。由于"$"符号是一個特殊字元,是以"$Dollar"被Shell嘗試解釋為"取出并列印Dollar變量的值“,如果恰巧你在系統中定義了這個變量并給予指派,那麼此處會列印出該變量的值,無論是哪種,都不是你原先想要的結果。這時就要使用"\"來轉義"$"字元,讓"$"失去其特殊含義,而隻作為一個符号出現。
二、引用
引用是指字元串用某種符号括起來,以防止特殊字元被解析為其他意思。比如說上一小節中的轉義符就是一種引用。Shell中一共有4種引用符,分别是雙引号、單引号、反引号和轉義符。其中雙引号又叫”部分引用"或“弱引用”,可以引用出除$符、反引号、轉義符之外的所有字元;單引号又叫“全引用”或“強引用",可以引用所有字元;反引号則會将反引号括起來的内容解釋為系統指令。
1.部分引用
部分引用是指雙引号括起來的引用。在這種引用的方式中,$符、反引号(`)、轉義符(\)這3種特殊字元依然會被解析為特殊意義。比如,在定義一個變量後,使用echo列印出變量的時候,将它們用雙引号括起來,如下所示:
#聲明變量VAR03,并用echo列印出來。第一次直接列印,第二次用引号括起來,從輸出内容看好像沒什麼差別
[root@Cfhost-170820-UCNK ~]# VAR03=100
[root@Cfhost-170820-UCNK ~]# echo $VAR03
100
[root@Cfhost-170820-UCNK ~]# echo "$VAR03"
#聲明變量VAR03,内容為字元串,ABC之間有多個空格
[root@Cfhost-170820-UCNK ~]# VAR04="A B C"
#直接列印變量時,輸出内容隻保留了每個字母間的一個空格
[root@Cfhost-170820-UCNK ~]# echo $VAR04
A B C
#使用引号括起來的輸出内容和變量定義時的内容完全一緻的
[root@Cfhost-170820-UCNK ~]# echo "$VAR04"
A B C
2.全引用
全引用是指用單引号括起來的引用。,單引号中的任何字元都隻當作是普通字元(除了單引号·本身,也就是說單引号中間無法再包含單引号,即便用轉義符轉義單引号也不行)。所有在單引号中間無法再包含單引号,即便用轉義符轉義單引号也不行)。所有在單引号中的字元都隻能代表其作為字元的字面意義
單引号和雙引号在很多時候是一樣的,隻是要記住,在雙引号中的$符、反引号、轉義符還是會被解析成其特殊含義,而在單引号中所有的字元都隻是字面意思。下面的例子中,使用雙引号括起的内容中,$PWD被解析成/root,而在單引号中隻是按照原樣輸出"$PWD“字元串。
3.指令替換
指令替換是指将指令的标準輸出作為值賦給某個變量。比如,在某個目錄中輸入ls指令檢視目前所有目錄中的檔案,但如何将輸出存入某個變量中呢?這就需要使用指令替換了,也就是Shell程式設計中使用最頻繁的功能。
Shell中有兩種方式可以完成指令替換,一種是反引号(`),一種是$(),使用方法如下:
運作系統指令date可以獲得目前的系統時間。在很多時候我們需要記錄腳本運作時間,是以隻是運作這個指令沒有什麼意義,必須将該指令的運作結果記錄并儲存到變量中,并持久化到檔案中,才能為後期分析提供有用的參考依據。
[root@Cfhost-170820-UCNK ~]# DATE_01=`date`
[root@Cfhost-170820-UCNK ~]# DATE_02=$(date)
[root@Cfhost-170820-UCNK ~]# echo $DATE_01
Tue Nov 28 19:48:47 MSK 2017
[root@Cfhost-170820-UCNK ~]# echo $DATE_02
Tue Nov 28 19:49:02 MSK 2017
如果被引用的指令輸出的内容包括多行,此時如果不通過引用的方式輸出變量,則輸出的内容中将會删除換行符,檔案名之間會使用系統預設的空來填充,即輸出的内容隻占一行。
[root@Cfhost-170820-UCNK ~]# LS=`ls -l`
[root@Cfhost-170820-UCNK ~]# echo $LS
total 64 -rw-r--r-- 1 root root 128 Nov 26 15:01 Awd.txt -rw-r--r-- 1 root root 77 Nov 26 16:33 bc.sh -rw-r--r-- 1 root root 39 Nov 26 16:32 cal.bc -rw-r--r-- 1 root root 50 Nov 26 16:10 Namespace01.sh -rw-r--r-- 1 root root 50 Nov 26 16:12 Namespace02.sh -rw-r--r-- 1 root root 192 Nov 26 16:17 Namespace03.c -rw-r--r-- 1 root root 137 Nov 26 16:14 Namespace03.sh -rw-r--r-- 1 root root 8
以上使用反引号的部分都可以使用$()進行替換,因為它們是等價的。但反引号畢竟和單引号看起來類似,有時候會對檢視代碼造成困難,而使用$()就相對清晰,能有效地避免這種混亂。但是有些情景是必須使用$()的:$()支援嵌套,而反引号不行。
補充說明:Shell中的運算符主要有比較運算符、字元串運算符、檔案操作運算符、邏輯運算符、算術運算符。
算術運算符,Java中和shell基本一緻
通常運算使用一個關鍵字 expr
使用該關鍵字注意:操作符和操作數之間必須以空格隔開,否則無法運算,打出的是字元串
4.特殊字元
通配符,常見的通配符有*、?和用[]括起來的字元序列。其中*代表任意長度的字元串。問号(?)可用于比對任一單個字元。方括号[]代表比對其中的任意一個字元.
引号,引号包括單引号和雙引号,單引号又稱“全引用”或“強引用”;雙引号又稱"部分引用“或弱引用",所有用雙引号括起來的出美元符、反斜杠、反引号依然保持其特殊用途外,其餘都作為普通字元處理;而所有用單引号括起的部分都作為普通字元處理,但是要注意單引号中間不能出現雙引号,否則Shell無法判斷到底哪裡是單引号的起止位置。
5.注釋符(通常用#,這個不用多說,注釋的目的在于增強代碼可讀性和有利于後期管理)
6.雜項
反引号用于指令替換,和$()的作用相同,表示傳回目前指令的執行結果并指派給變量。
位置參數:
$0:腳本本身
$1、$2...${10}:腳本的第一個參數、第二個參數到第十個參數
$#:變量總數
$*、$@:顯示所有參數
$?:前一個指令退出的傳回值
$!:最後一個背景程序的ID号
!:通常代表取反