分類: Linux 2008-05-20 20:01 540人閱讀 評論(0) 收藏 舉報
Overview
wildcard是由shell處理的, 它只會出現(xiàn)在 command的argument 里——既不用在 command_name里, 也不用在 options 上。當在argument中碰到Wildcard時,shell會將其當作路徑或文件名去在磁盤上搜尋可能的匹配:若符合要求的匹配存在,則進行代換(路徑擴展);否則就將該wildcard作為一個普通字符傳遞給command,交由command自行處理??偠灾?,wildcard 實際上就是一種shell實現(xiàn)的路徑擴展功能。在 wildcard 被處理后, shell會先完成該命令的重組,然后再繼續(xù)處理重組后的命令,直至執(zhí)行該命令。
例如,若當前目錄下有Cha1、Cha2和Des三個文件,而我想用grep在Des中搜索包含字符串Cha的行,于是寫出命令如下:
grep Cha* Des ①
當該命令交由shell處理時,首先會將Cha*中的*當作是一個wildcard,于是就會在當前目錄中搜索可能的匹配。*作為wildcard而言匹配的是0個或多個的任意字符,于是文件Cha1和Cha2符合匹配要求,shell自行完成了該命令的重組,重組后的命令為:
grep Cha1 Cha2 Des ②
而這才是最終執(zhí)行的命令的文本形式。所以命令①實際上的動作是試圖在文件Cha2和Des中尋找包含Cha1字符串的行。這和期望grep所作的動作是大相徑庭的。
可是,如果當前目錄下沒有可以匹配Cha*的文件或是文件夾(路徑),那么shell會因為找不到可能的匹配而放棄*號的代換,將其傳遞給command處理,重組后的命令如下:
grep Cha* Des ③
這也是該情況下最終執(zhí)行的命令的文本形式。在這種情況下命令①的動作和預(yù)期的動作卻也不是一致的。因為當*號交給grep處理時,*號將不再是表示0個或多個任意的字符了——這是它作為wildcard,在shell中處理時的含義——在grep的處理中,*號是被當作正則表達式中的符號,表示的是其前面的字符出現(xiàn)0次或多次。
若是在第一種情況下,如何才能使重組后的命令為命令③,而非命令②呢?在shell的命令中,所有的文字可以分為meta 與 literal:literal就是普通的純文字,對于shell來說沒有什么特別的意義;meta則是shell中具有特定功能的特殊保留字符,如< > |等。不嚴格區(qū)分的話,wildcard也可以歸入這一類。也就是說,meta就是會在shell中被處理的從而在最終用于執(zhí)行的命令中喪失了其自身文本形式的特殊字符(從這個角度來說,將wildcard歸入meta是有些不妥的,因為wildcard的有可能被替換掉也有可能不被替換)。若是希望能夠?qū)hell中的meta以其文本形式進入command的最終執(zhí)行形態(tài)中——像前面我們所希望的一樣,就必須告訴shell不要對meta進行處理,command需要使用它們的文本形式。這個工作則是由shell quoting(轉(zhuǎn)義)來完成的。這種處理正是使用regular expression(正則表達式)所必需要用到的:因為regular expression(正則表達式)中有許多特殊字符(可以看作是RE中的meta)和shell中的meta及wildcard是相同的,所以為了讓那些regular expression中的特殊字符能夠通過shell傳入regular expression就必須對其進行轉(zhuǎn)義。同樣,在那些定義了自有的meta的命令中,若是自有的meta與shell中的meta或wildcard重復(fù),也要用到shell quoting,如tr。
Wildcard
* 匹配 0 或多個字符
? 匹配任意單一字符
[list] 匹配 list 中的任意單一字符
[!list] 匹配不在 list 中的任意單一字符
{string1,string2,...} 匹配 sring1 或 string2 (或更多)其一字符串
例:
a*b a與b之間可以有任意長度的任意字符, 也可以一個也沒有, 如aabcb, axyzb, a012b, ab。
a?b a與b之間必須也只能有一個字符, 可以是任意字符, 如aab, abb, acb, a0b。
a[xyz]b a與b之間必須也只能有一個字符, 但只能是 x 或 y 或 z, 如: axb, ayb, azb。
a[!0-9]b a與b之間必須也只能有一個字符, 但不能是阿拉伯數(shù)字, 如axb, aab, a-b。
a{abc,xyz,123}b a與b之間只能是abc或xyz或123這三個字符串之一。
shell中的meta
下面是一些常用的:
IFS 由 <space> 或 <tab> 或 <enter> 三者之一組成(我們常用 space )。
CR 由 <enter> 產(chǎn)生。
= 設(shè)定變量。
$ 作變量或運算替換(請不要與 shell prompt 搞混了)。
> 重導(dǎo)向 stdout。
< 重導(dǎo)向 stdin。
| 命令管線。
& 重導(dǎo)向 file descriptor ,或?qū)⒚钪糜诒尘硤?zhí)行。
( ) 將其內(nèi)的命令置于 nested subshell 執(zhí)行,或用于運算或命令替換。
{ } 將其內(nèi)的命令置于 non-named function 中執(zhí)行,或用在變量替換的界定范圍。
; 在前一個命令結(jié)束時,而忽略其返回值,繼續(xù)執(zhí)行下一個命令。
&& 在前一個命令結(jié)束時,若返回值為 true,繼續(xù)執(zhí)行下一個命令。
|| 在前一個命令結(jié)束時,若返回值為 false,繼續(xù)執(zhí)行下一個命令。
! 執(zhí)行 history 列表中的命令。
Shell Quoting
一共有三種轉(zhuǎn)義字符,它們實際上也可以看作是shell中的meta:
‘’(單引號):
又叫hard quote,其內(nèi)部所有的shell meta都會被關(guān)掉。注意,hard quote中不允許出現(xiàn)’(單引號)。
“”(雙引號):
又叫soft quote,其內(nèi)部只允許出現(xiàn)特定的shell meta:
$ 用于參數(shù)代換
` 反引號,用于命令代換
/$ 實現(xiàn)美元標志
/’ 實現(xiàn)反引號的文本化(去除反引號的特殊意義)
/” 實現(xiàn)雙引號的文本化(去除雙引號的特殊意義)
// 實現(xiàn)反斜杠的文本化(去除反斜杠的特殊意義)
注意,在soft quote中單引號沒有特殊意義,就是文本。
/(反斜杠):
又叫escape,去除其后緊跟的meta或wildcard的特殊意義。
實際上quote的使用就是為了跳過shell對特殊字符的處理。
Regular Expression
錨點(anchor):
用以標識 RE 于句子中的位置所在. 常見有:
^ 表示句首. 如 ^abc 表示以 abc 開首的句子.
$ 表示句尾. 如 abc$ 表示以 abc 結(jié)尾的句子.
/< 表示詞首. 如 /<abc 表示以 abc 開首的詞.
/> 表示詞尾. 如 abc/> 表示以 abc 結(jié)尾的詞.
修飾字符(modifier):
獨立表示時本身不具意義, 專門用以修改前一個字元集的出現(xiàn)次數(shù). 常見有:
* 表示前一個字元集的出現(xiàn)次數(shù)為0或多次。如ab*c表示a與c之間可有0或多個b存在。
? 表示前一個字元集的出現(xiàn)次數(shù)為0或1次。如ab?c表示a與c之間可有0或1個b存在。
+ 表示前一個字元集的出現(xiàn)次數(shù)為1或多次。如ab+c表示a與c之間可有1或多個b存在。
{n} 表示前一個字元集的出現(xiàn)次數(shù)必須為n次. 如ab{3,}c表示 a與c之間必須有3個b存在。
{n,} 表示前一個字元集的出現(xiàn)次數(shù)至少為n次. 如ab{3,}c表示a與c之間至少有3個b存在。
{n,m} 表示前一個字元集的出現(xiàn)次數(shù)為n到m次. 如ab{3,5}c表示a與c之間有3到5個b存在。
總結(jié)
總的來說,正是因為shell中的meta、wildcard有時會和command中的meta相同,為了讓command中的meta不被shell解析以至于改變,就必須用shell quoting來保證其文字不變性。
附:shell腳本的解釋過程

需要注意的是,double quote中的內(nèi)容跳過了1-4步和9-10步,single quote中的內(nèi)容跳過了1-10步。也就是說,double quote只經(jīng)過參數(shù)擴展、命令代換和算術(shù)代換就可以送入執(zhí)行步驟,而single quote直接會被送入執(zhí)行步驟。而且,無論是double quote還是single quote在執(zhí)行的時候能夠告訴各個命令自身內(nèi)部是一體的,但是其本身在執(zhí)行時是并不是命令中文本的一部分。
如
Lsdetail=”ls –l”
$Lsdetail
執(zhí)行的就是ls –l,而double quote并不是執(zhí)行命令的一部分。
愛華網(wǎng)


