1. 程式人生 > >從 shell 眼中看世界

從 shell 眼中看世界

討論 可能 打印 logs 文件路徑 開頭 一次 目錄下的文件 嵌入

(字符) 展開
每一次你輸入一個命令,然後按下 enter 鍵,在 bash 執行你的命令之前, bash 會對輸入的
字符完成幾個步驟處理。我們已經知道兩三個案例,怎樣一個簡單的字符序列,例如 “*”,
shell 來說,有很多的涵義。使這個發生的過程叫做(字符)展開。通過展開,你輸入的字符,
shell 對它起作用之前,會展開成為別的字符。為了說明我們所要表達的意思,讓我們看一
echo 命令。echo 是一個 shell 內部命令,來完成非常簡單的認為。它在標準輸出中打印出它
的文本參數。

技術分享

那麽剛才發生了什麽事情呢?為什麽 echo 不打印 “*” 呢?隨著你回想起我們所學過的關於
通配符的內容,這個 “*” 字符意味著匹配文件名中的任意字符,但是在原先的討論中我們卻不

知道 shell 是怎樣實現這個功能的。最簡單的答案就是 shell “*” 展開成了另外的東西(在這
種情況下,就是在當前工作目錄下的文件名字),在 echo 命令被執行前。當回車鍵被按下時,
shell 在命令被執行前在命令行上自動展開任何符合條件的字符,所以 echo 命令從不會發現
“*”, 只把它展開成結果。知道了這個以後,我們能看到 echo 執行的結果和我們想象的一樣。

路徑名展開
這種通配符工作機制叫做路徑名展開。如果我們試一下在之前的章節中使用的技巧,我們
會看到它們真是要展開的字符。給出一個主目錄,它看起來像這樣:
技術分享

技術分享

查看主目錄之外的目錄:

技術分享

隱藏文件路徑名展開
正如我們知道的,以圓點字符開頭的文件名是隱藏文件。路徑名展開也尊重這


種行為。像這樣的展開:
echo *
不會顯示隱藏文件
要是展開模式以一個圓點開頭,我們就能夠在展開模式中包含隱藏文件,而且
隱藏文件可能會出現在第一位置,就像這樣:
echo .*
它幾乎是起作用了。然而,如果我們仔細檢查一下輸出結果,我們會看到名字
“.” “..” 也出現在結果中。因為這些名字是指當前工作目錄和它的父目錄,使用這
種模式可能會產生不正確的結果。我們能看到這樣的結果,如果我們試一下這個命
令:
ls -d .* | less
為了在這種情況下正確地完成路徑名展開,我們應該雇傭一個更精確些的模式。
這個模式會正確地工作:
ls -d .[!.]?*
這種模式展開成為文件名,每個文件名以圓點開頭,第二個字符不包含圓點,

再包含至少一個字符,並且這個字符之後緊接著任意多個字符。這將列出大多數的
隱藏文件(但仍將不能包含以多個圓點開頭的文件名)這個帶有 -A 選項(“幾乎所
有”)的 ls 命令能夠提供一份正確的隱藏文件清單:
ls -A

正則表達式的東西在之後的隨筆講解。

波浪線展開
可能你從我們對 cd 命令的介紹中回想起來,波浪線字符 (“”) 有特殊的意思。當它用在一
個單詞的開頭時,它會展開成指定用戶的主目錄名,如果沒有指定用戶名,則是當前用戶的主
目錄:
技術分享

算術表達式展開
shell 允許算術表達式通過展開來執行。這允許我們把 shell 提示當作計算器來使用:

技術分享

(以上括號中的)表達式是指算術表達式,它由數值和算術操作符組成。
算術表達式只支持整數(全部是數字,不帶小數點),但是能執行很多不同的操作。這裏是
一些它支持的操作符:

技術分享

技術分享

技術分享

花括號展開
可能最奇怪的展開是花括號展開。通過它,你可以從一個包含花括號的模式中創建多個文
本字符串。這是一個例子:

技術分享

花括號展開模式可能包含一個開頭部分叫做報頭,一個結尾部分叫做附言。花括號表達式
本身可能包含一個由逗號分開的字符串列表,或者一系列整數,或者單個的字符串。這種模式
可能不包括嵌入的空白。這個例題使用了一系列整數:

技術分享

那麽這對什麽有好處呢?最普遍的應用是,創建一系列的文件或目錄列表。例如,如果我
們是攝影師,有大量的相片。我們想把這些相片按年月先後組織起來。首先,我們要創建一系
列以數值 年-月形式命名的目錄。通過這種方式,目錄名按照年代順序排列。我們可以鍵
入整個目錄列表,但是工作量太大了,並且易於出錯。反而,我們可以這樣做:

技術分享

從 shell 眼中看世界