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"
100
#聲明變量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號
!:通常代表取反