1. 程式人生 > >Shell特殊字元

Shell特殊字元

1.Shell簡介

shell既是類Unix作業系統的命令解析器,用於解釋執行使用者輸入的一連串命令,它類似於DOS下的command和後來Windows的cmd.exe。同時shell也是一種程式設計語言。作為命令解釋型的指令碼語言,它互動式解釋和執行使用者輸入的命令或者自動地解釋和執行預先設定好的一連串的命令;作為程式設計語言,它預定義了各種環境變數,保留了一些關鍵字以及一些特殊字元的含義,並提供了許多在高階語言中才具有的控制結構,包括迴圈和分支判斷。

這裡再簡要的介紹一下shell的分類以及常見的shell。

基本上Shell分兩大類:
一:圖形介面Shell(Graphical User Interface Shell 即 GUI Shell)
例如:應用最為廣泛的 Windows Explorer (微軟的windows系列作業系統),還有也包括廣為人知的 Linux shell,其中linux shell 包括 X window manager (BlackBox和FluxBox),以及功能更強大的CDE、GNOME、KDE、 XFCE。

二:命令列式Shell(Command Line Interface Shell ,即CLI Shell)
常見的命令列式Shell,按照問世時間排序有最早的Bourne Shell(sh)、後來的C Shell(csh)、AT&T公司的貝爾實驗室開發的Korn Shell ( ksh)、GNU的Bourne Again Shell (bash)、POSIX Shell等。我們最長見的應該算是bash了。

2.Shell常見特殊字元

Shell的特殊字元非常的繁雜,各種特殊的符號在我們編寫Shell指令碼的時候如果能夠用得好,往往能起到事半功倍的效果。為此,特地將shell裡面的一些常見特殊符號歸類並羅列成對照表的形式,以便快速的查詢。看看你知道或者用過下表中你的哪些Shell符號呢?

Shell常見特殊字元可以分為以下幾類:特殊變數,替換符,轉義字元,字串符(引號),功能符,運算子。

2.1 特殊變數

序號 符號 作用 示例
1 $0 當前指令碼的名稱
2 $# 傳遞給指令碼或函式的引數個數
3 $* 傳遞給指令碼或函式的所有引數
4 [email protected] 傳遞給指令碼或函式的所有引數。被雙引號”“包含時,與 $* 稍有不同,下面將會講到
5 $? 上個命令的退出狀態,或函式的返回值。
6 $$ 當前Shell程序ID。對於 Shell 指令碼,就是這些指令碼所在的程序ID。
7 $n 傳遞給指令碼或函式的引數。n 是一個數字,表示第幾個引數。例如,第一個引數是$1,第二個引數是$2。
8 * 作為匹配檔名擴充套件的一個萬用字元,能自動匹配給定目錄下的每一個檔案。
9 ~ 波浪號(Home directory[tilde]),這個和shell環境變數$HOME是一樣的。預設表示當前使用者的家目錄(主目錄) echo ~,檢視家目錄。
10 - - 兩個減號,與~相同,表示當前使用者的家目錄(主目錄) cd - -,回到家目錄。不能echo - - 來列印輸出。
11 ~+ 當前的工作目錄(current working directory)。這個和shell環境變數$PWD一樣。 echo ~+可以檢視當前目錄。
12 ~- 前一個工作目錄(previous working directory)。這個和內部變數$OLDPWD一致,和減號-一樣。 echo ~-可以檢視前一個工作目錄。
13 - 減號。和~-一樣,表示前一個工作目錄。 cd -,回到前一個工作目錄,不能echo - 來檢視。


關於上面的特殊變數的幾個知識點:
(1)$@與$*的區別?
$@和$*都表示指令碼或者函式傳入的引數,不被雙引號”“包含時,都以$1 $2 … $n的形式輸出所有引數。

但是當它們被雙引號”“包含時,"$*" 會將所有的引數作為一個整體,以"$1 $2 … $n"的形式輸出所有引數。但是"[email protected]"[email protected]一樣,還是會將各個引數分開,以$1 $2 … $n的形式輸出所有引數。

具體參考如下示例:

function print(){
    echo "param num:"$#
    for i in "$*"
    do
        echo param:$i
    done

    for i in "[email protected]"
    do
        echo param:$i
    done
    echo "all param:"$*
    echo "all param:"[email protected]
    echo param1:$1
    echo param2:$2

    return 12
}

print "lvlv0" "lvlv1"
echo $?
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

執行指令碼,輸出結果:

param num:2
param:lvlv0 lvlv1
param:lvlv0
param:lvlv1
all param:lvlv0 lvlv1
all param:lvlv0 lvlv1
param1:lvlv0
param2:lvlv1
12
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

2.2替換符

替換符又分為命令替換符變數替換符

下面是變數替換符。

序號 符號 作用 示例
14 $ 美元符,放在變數前用於取變數的值,比如$PATH
15 ${} 美元符加上大括號,大括號中放變數的名稱,也是用於讀取變數的值 echo ${PATH}path,訪問變數PATH,而不是變數PATHpath,注意和上面$的區別
16 ${:-} 用法${var:-word}。表示如果變數 var 為空或已被刪除(unset),那麼返回 word,但不改變 var 的值。
17 ${:+} 用法${var:+word}。如果變數 var 被定義,那麼返回 word,但不改變 var 的值。
18 ${:=} 用法${var:=word}。如果變數 var 為空或已被刪除(unset),那麼返回 word,並將 var 的值設定為 word。
19 ${:?} 用法${var:?message}。如果變數 var 為空或已被刪除(unset),那麼將訊息 message 送到標準錯誤輸出,可以用來檢測變數 var 是否可以被正常賦值。若此替換出現在Shell指令碼中,那麼指令碼將停止執行。
20 ${#} 用法${#var}。獲取字串變數var的長度 string="abcd";echo ${#string} #輸出4
21 ${:} 字串提取,用法${var:num}。這種模式時,shell在var中提取第num個字元到末尾的所有字元。若num為正數,從左邊0處開始;若num為負數,從右邊開始提取字串,但必須使用在冒號後面加空格或一個表示式或整個num加上括號,如${var: -2}、${var:1-4}或${var:(-2)} a="abcde";echo ${a:1-4},輸出cde。
22 ${::} 字串提取,用法${var:n1:n2}。 string="tencent is a great company";echo ${string:1:4},輸出ence。
23 {,} 用法${value1,value2,value3}。逗號分割一般用於檔案列表的擴充套件。 echo {a,b}.txt,輸出a.txt b.txt。
24 {..} 用法${value1..value2}。用於順序擴充套件。 touch {a..d}.txt,結果為a.txt b.txt c.txt d.txt
25 ${#} 模式匹配截斷,用法${variable#pattern} 這種模式時,shell在variable中查詢給定的模式pattern,如果找到,就從命令列把variable中的內容去掉左邊最短的匹配模式。不改變原變數。 var=testcase; echo ${var#*s},輸出tcase。
26 ${##} 模式匹配截斷,用法${variable##pattern} 這種模式時,shell在variable中查詢給定的模式pattern,如果是存在,就從命令列把variable中的內容去掉左邊最長的匹配模式。不改變原變數。 var=testcase; echo ${var##*s},輸出e。
27 ${%} 模式匹配截斷,用法${variable%pattern},這種模式時,shell在variable中查詢,看它是否一給的模式pattern結尾,如果是,就從命令列把variable中的內容去掉右邊最短的匹配模式。不改變原變數。 var=testcase;echo ${var%s*e},結果為testca。
28 ${%%} 模式匹配截斷,用法${variable%%pattern},這種模式時,shell在variable中查詢,看它是否一給的模式pattern結尾,如果是,就從命令列把variable中的內容去掉右邊最長的匹配模式。不改變原變數。 var=testcase;echo ${var%%s*e},結果為te。
29 ${/ /} 模式匹配替換。${var/pattern/pattern}表示將var字串的第一個匹配的pattern替換為另一個pattern。不改變原變數。 var=/home/centos;echo ${var/o/h}結果為/hhme/centos
30 ${// /} 模式匹配替換。${var//pattern/pattern}表示將var字串中的所有能匹配的pattern替換為另一個pattern。不改變原變數。 var=/home/centos;echo ${var//o/h}結果為/hhme/cenths
31 $[] 整數擴充套件(integer expansion),在方括號內執行整數表示式並返回結果。 a=3;b=7;echo $[$a+$b]輸出10。


注意:上面的模式不符合正則表示式的規則。


下面是命令替換符。

序號 特殊符號 作用 示例
33 $() 美元符加小括號,命令替換符,用於執行命令,替換命令的輸出結果 echo $(date)
34 ` ` 一對反引號,在鍵盤的Tab鍵上面,注意與單引號的區別,其作用與$()相同 echo `date`

2.3轉義字元

下面的轉義字元都可以用在 echo 中:

序號 符號 作用 示例
35 \ 反斜槓,用於轉義。
36 \a 警報,響鈴
37 \b 退格(刪除鍵)
38 \f 換頁(FF),將當前位置移到下頁開頭
39 \n 換行
40 \r 回車
41 \t 水平製表符(tab鍵)
42 \v 垂直製表符
43 \c produce no further output,不產生進一步的輸出。也就是說在\c後,這一行後面的內容都不會輸出,直接刪掉了 echo -e "this is line1 \c these word will disappear",輸出:this is line1。

可以使用 echo 命令的-e選項啟動轉義, -E 選項禁止轉義,預設也是不轉義的。禁止轉義的話也就無法識別上面除反斜槓外的其它的轉義字元了,比如echo "\n" 是不會換行的,而是輸出\n,如果換行的話,使用echo -e \n

2.4字串符(引號)

序號 符號 作用 示例
45 兩個單引號。單引號括住的內容,被視為常量字串,引號內的禁止變數擴充套件,並且單引號字串中不能出現單引號(對單引號使用轉義符後也不行) echo '$PATH';#輸出$PATH
46 “” 兩個雙引號。雙引號包圍的內容可以允許變數擴充套件,可以包含雙引號,但需要轉義。 echo '$PATH;#輸出環境變數PATH的內容

2.5功能符

功能符號,我在這裡把它分為兩類。第一類是語法功能符,第二類是命令功能符。具體詳見下文。

語法功能符。

序號 符號 作用 示例
48 # 井號。註釋符號。在shell檔案的行首,作為include標記,#!/bin/bash;其他地方作為註釋使用。
49 ; 分號。語句的分隔符。在shell檔案一行寫多條語句時,使用分號分割。
50 ;; 雙分號。在使用case選項的時候,作為每個選項的終結符。在Bash version 4+ 的時候,還可以使用[;;&], [;&]
51 / 斜槓。路徑的分隔符,路徑中僅有一個斜杆表示根目錄,以斜杆開頭的路徑表示從根目錄開始的路徑。
52 | 管道(pipe)。管道是Linux,Unix都有的概念,是非常基礎,也是非常重要的一個概念。它的作用是將管道前(左邊)的命令產生的輸出(stdout)作為管道後(右邊)的命令的輸入(stdin)。 less fiel|wc -l, 用於統計檔案的行數。
53 > 輸出重定向。 echo lvlv>file,將標準輸出重定向檔案file中去,如果檔案存在則覆蓋,不能存在則建立。不指定輸出的內容,>file,則清空檔案。
54 >> 輸出重定向追加符。 echo lvlv 1>>file,將標準輸出重定向檔案file的最後面,不會覆蓋file原有內容
55 >& 輸出重定向等同符,作用於檔案描述符,即左右兩邊的運算元是檔案描述符 echo lvlv>file 2>&1,標準輸出重定向到檔案file中,標準錯誤輸出與標準輸出重定向一致
56 &> 標準輸出和標準錯誤輸出重定向符。 echo lvlv &>file,標準輸出和標準錯誤輸出都重定向到檔案file中,與echo lvlv 1>file 2>&1 功能相同
57 < 輸入重定向 test.sh < file,指令碼test.sh需要read的地方會從檔案file讀取
58 << 用法格式:cmd << text。從命令列讀取輸入,直到一個與text相同的行結束。除非使用引號把輸入括起來,此模式將對輸入內容進行shell變數替換。如果使用<<- ,則會忽略接下來輸入行首的tab,結束行也可以是一堆tab再加上一個與text相同的內容。
59 <& 標準輸入重定向等同符,作用於檔案描述符,即左右兩邊的運算元是檔案描述符 cmd <& m,將檔案描述符m作為cmd的輸入,省略了標準輸入描述符1,即等價於cmd 1<&fd
60 >&- 關閉某個輸出檔案描述符。用法格式:exec fd>&- exec >&-exec 0>&-,關閉標準輸出
61 <&- 關閉某個輸入檔案描述符。用法格式:exec fd>&- exec <&-exec 1<&-關閉標準輸入
62 & 與號。如果命令後面跟上一個&符號,這個命令將會在後臺執行。 使用格式:command&
63 / 斜槓。主要有兩種作用。
(1)作為路徑的分隔符,路徑中僅有一個斜杆表示根目錄,以斜杆開頭的路徑表示從根目錄開始的路徑;
(2)在作為運算子的時候,表示除法符號。
64 () 一對小括號。主要有兩種用法:
(1)命令組。括號中的命令將會新開一個子shell順序執行,所以括號中的變數不能夠被指令碼餘下的部分使用。括號中多個命令之間用分號隔開,最後一個命令可以沒有分號,各命令和括號之間不必有空格。
(2)用於初始化陣列。如:array=(a b c d)
65 {} 一對大括號,程式碼塊識別符號。一般用於函式定義時表明函式體。
66 <<< 三個小於號,作用就是將後面的內容作為前面命令的標準輸入。 grep a <<< "$VARIABLE", 意思就是在VARIABLE這個變數值裡查詢字元a。
67 >| 大於號與豎槓。功能同>,但即便設定了noclobber屬性時也會強制覆蓋file檔案。shell設定了noclobber屬性表明已存在的檔案不能被重定向輸出覆蓋。
68 <> 標準輸入與輸出重定向運算子 exec 6<>filename,通過exec命令,以讀寫的方式將檔案描述符6繫結到指定檔案


命令功能符。

序號 符號 作用 示例
61 . 點號。
1.相當於bash內建命令source,如:
#!/bin/bash;
. data-file#包含data-file;
2.作為檔名的一部分,在檔名的開頭,表示該檔案為隱藏檔案,ls一般不顯示出來(ls -a 可以顯示);
3.作為目錄名,一個點代表當前目錄,兩個點號代表上層目錄(當前目錄的父目錄)。注意,兩個以上的點不出現,除非你用引號(單/雙)包圍作為點號字元本身;
4.正則表示式中,點號表示任意一個字元。
62 : 冒號。是shell的空命令(null command),什麼也不做,但是返回true。用法比較多,主要有:
(1)可做while死迴圈的條件;
(2)佔位符,if某一分支什麼都不做的時候;
(3)域分隔符,比如環境變數$PATH中,或者passwd中,都有冒號的作為域分隔符的存在;
(4)清空檔案。因為冒號不向標準輸出任何內容,所以可以用來清空檔案,示例::>file
(5)配合${:=}給未定義或為空的變數賦值,示例:: ${abc:=1234};echo $abc,輸出1234

2.6運算子

shel的運算子比較多,大致可以分為如下幾類:算數運算子、關係運算符、邏輯運算子、字串運算子和檔案測試運算子。

算術運算子。

序號 符號 作用 示例
62 + 加法 a=10;b=20;expr $a + $b結果為30。注意空格。
63 - 減法 expr $a - $b 結果為-10。
64 * 乘法 expr $a * $b 結果為200。
65 / 除法 expr $b / $a 結果為2。
66 % 取餘 expr $b % $a 結果為 0。
67 = 賦值 a=$b,將把變數 b 的值賦給 a。
68 (()) 雙小括號算術運算子,用於expr命令的替代,即支援演算法表示式,而無需expr命令 比如for((i=0;i<10;++i))或者((out=$a*$b))或者if(($a==$b));then ... fi,無需新增空格了,更加符合C的程式設計語法
69 ** 雙星號(double asterisk)。算術運算中表示求冪運算。
70 , 逗號運算子comma operator。用法主要有兩個:
(1)用在連線一連串的數學表示式中,這串數學表示式均被求值,但只有最後一個求值結果被返回。如:
(2)用於引數替代中,表示首字母小寫,如果是兩個逗號,則表示全部小寫,注意,這個特性在bash version 4的時候被新增的。
示例見下文。


逗號運算子用法示例:
(1)用在連線一連串的數學表示式中。

#!/bin/bash
let t1=((a=5+1, b=7+2))
echo t1=$t1, a=$a, b=$b
## 這個$t1=$b;
  
  • 1
  • 2
  • 3
  • 4

(2)用於引數替代中。

a="ATest"
echo ${a,}
echo ${a,,}
## 前面輸出aTest,後面輸出的是atest。
  
  • 1
  • 2
  • 3
  • 4

關係運算符。

序號 符號 作用 示例
71 [] 一對方括號,用於判斷條件是否成立 [ $a == $b ],注意新增4個空格
72 [[]] 兩對方括號,是對[]的擴充套件,可使用<、>、&&、||等運算子 [[ $a>$b ]],只需要新增左右兩邊兩個空格,需要注意:使用==與!=時,仍需要4個空格
73 -eq 檢測兩個數是否相等,相等返回 true。 [ $a -eq $b ] 返回 true。
74 == 檢測兩個數是否相等,作用同-eq [ $a == $b ] 返回 true。
75 -ne 檢測兩個數是否相等,不相等返回 true。 [ $a -ne $b ] 返回 true。
76 != 作用同-ne
77 -gt 檢測左邊的數是否大於右邊的,如果是,則返回 true。 [ $a -gt $b ] 返回 false。
78 -lt 檢測左邊的數是否小於右邊的,如果是,則返回 true。 [ $a -lt $b ] 返回 true。
79 -ge 檢測左邊的數是否大等於右邊的,如果是,則返回 true。 [ $a -ge $b ] 返回 false。
80 -le 檢測左邊的數是否小於等於右邊的,如果是,則返回 true。 [ $a -le $b ] 返回 true。


注意:
(1)運算子[]與[[]]的區別
[]實際上是bash 中 test 命令的簡寫。即所有的 [ expression ] 等於 test expression。而[[ expr ]]是bash中真正的條件判斷語句,其語法更符合程式設計習慣,建議使用。

(2)shell中沒有<=與>=運算子,只能使用-le-ge替代。

邏輯運算子。

序號 符號 作用 示例
82 ! 非運算,表示式為 true 則返回 false,否則返回 true。 [ ! false ] 返回 true。
83 -o 或運算,有一個表示式為 true 則返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。
84 -a 與運算,兩個表示式都為 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。
85 || 或運算子,與&&作用相反,也有兩種用法。
(1)用於條件判斷,需與[[]]配合使用。兩個表示式有一個為true就返回true。
(2)命令連線。command1 || command2。左邊的命令返回false(即返回非0,執行失敗),||右邊的命令才能夠被執行。
[[ $a < 20 || $b > 100 ]]返回true。
86 && 與運算子,有兩種用法。
(1)用於條件判斷,需與[[]]配合使用。兩個表示式都為true才返回true。
(2)命令連線。command1 && command2。左邊的命令返回真(即返回0,成功被執行),&&右邊的命令才能夠被執行。
[[ $a < 20 && $b > 100 ]] 返回 false。


字串運算子。

序號 符號 作用 示例
87 = 檢測兩個字串是否相等,相等返回 true。 [ $a = $b ] 返回 false。
88 != 檢測兩個字串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。
89 -z 檢測字串長度是否為0,為0返回 true。 [ -z $a ] 返回 false。
90 -n 檢測字串長度是否為0,不為0返回 true。 [ -z $a ] 返回 true。
91 str 檢測字串是否為空,不為空返回 true。 [ $a ] 返回 true。
92 =~ 正則表示式匹配運算子,用於匹配正則表示式的,配合[[]]使用 if [[ ! $file =~ check$ ]],用於判斷$file是否是以check結尾


檔案測試運算子。
檔案測試運算子用於檢測 Unix 檔案的各種屬性。

序號 符號 作用 示例
94 -b 檢測檔案是否是塊裝置檔案,如果是,則返回 true。 [ -b $file ] 返回 false。
95 -c 檢測檔案是否是字元裝置檔案,如果是,則返回 true。 [ -b $file ] 返回 false。
96 -d 檢測檔案是否是目錄,如果是,則返回 true。 [ -d $file ] 返回 false。
97 -f 檢測檔案是否是普通檔案(既不是目錄,也不是裝置檔案),如果是,則返回 true。 [ -f $file ] 返回 true。
98 -g 檢測檔案是否設定了SGID 位,如果是,則返回 true。 [ -g $file ] 返回 false。
99 -k 檢測檔案是否設定了粘著位(Sticky Bit),如果是,則返回 true。 [ -k $file ] 返回 false。
100 -p 檢測檔案是否是具名管道,如果是,則返回 true。 [ -p $file ] 返回 false。
101 -u 檢測檔案是否設定了 SUID 位,如果是,則返回 true。 [ -u $file ] 返回 false。
102 -r 檢測檔案是否可讀,如果是,則返回 true。 [ -r $file ] 返回 true。
103 -w 檢測檔案是否可寫,如果是,則返回 true。 [ -w $file ] 返回 true。
104 -x 檢測檔案是否可執行,如果是,則返回 true。 [ -x $file ] 返回 true。
105 -s 檢測檔案是否為空(檔案大小是否大於0),不為空返回 true。 [ -s $file ] 返回 true。
106 -e 檢測檔案(包括目錄)是否存在,如果是,則返回 true。 [ -e $file ] 返回 true。


這裡附帶說明一下Linux下檔案的型別。
- 普通檔案
d 目錄
b 塊裝置
c 字元裝置
p 命名管道
l 符號連結
s 套接字

3.小結

斷斷續續歷時3個多星期,終於完成了這篇blog,中途遇到了新的特殊字元,我會及時更新加進去。

是不是被上面的多如繁星的特殊字元弄的暈頭轉向,你都瞭解和用過嗎?其實沒有必要花費大量的時間去死記硬背,可當做手冊參考,在需要使用的時候再去了解其意義和用法是不遲的。

shell的特殊字元真的是太多了,我可以很負責任的告訴你,上面總結的其實只是一部分,還有很多沒有列出來。對於上面特殊字元的解釋,因未參考到權威的資料,再加上本人有些字元未親自實踐和使用過,所以有些解釋難免片面甚至錯誤,僅供參考!如有錯誤的地方,也請大家勿吝指教,留言告知,共同學習!如果大家在專案中使用了上面未列出的特殊字元,也請留言告知,幫助完善本篇文章,thx!


參考文獻

[1]Linux下高效編寫Shell——shell特殊字元彙總
[2]Linux Shell指令碼教程:30分鐘玩轉Shell指令碼程式設計
[3]LINUX ECHO 用法 【 -E \C 體會】
[4]shell中各種括號的作用()、(())、[]、[[]]、{}
[5]實現ll命令
[6]shell指令碼中一些特殊符號
[7]linux shell資料重定向

1.Shell簡介

shell既是類Unix作業系統的命令解析器,用於解釋執行使用者輸入的一連串命令,它類似於DOS下的command和後來Windows的cmd.exe。同時shell也是一種程式設計語言。作為命令解釋型的指令碼語言,它互動式解釋和執行使用者輸入的命令或者自動地解釋和執行預先設定好的一連串的命令;作為程式設計語言,它預定義了各種環境變數,保留了一些關鍵字以及一些特殊字元的含義,並提供了許多在高階語言中才具有的控制結構,包括迴圈和分支判斷。