使用 ^ 作為 shell 元字元
我今天寫了一個小腳本,其中包含
grep -q ^local0 /etc/syslog.conf
在審查期間,一位同事建議
^local0
引用它,因為^
在 Bourne shell 中的意思是“管道”。對這種說法感到驚訝,我試圖追查任何提到這一點的參考資料。我在網際網路上發現的任何內容都沒有表明這是一個問題。然而,事實證明,
bsh
在 AIX 7 上的實現(聲稱是 Bourne shell)實際上具有以下行為:> bsh $ ls ^ wc 23 23 183 $ ls | wc 23 23 183
我嘗試過的其他“Bourne shell”實現都沒有這種行為(也就是說,
^
根本不被視為 shell 元字元)。sh
我在 CentOS(它真的是 bash)和sh
FreeBSD(它不是 bash)上試過。我沒有很多其他系統可以嘗試。這種行為是預期的嗎?哪些 shell 認為
^
是管道元字元?
^
作為同義詞的字元|
可以追溯到Thompson shell。它們在 Unix v4 中同時引入,並在手冊頁中一起提到。Sven Mascheck提到^
“可能$$ introduced $$出於方便的原因,在早期僅使用大寫字母的終端上”打字
|
“有點痛苦”。 Thompson shell 早已不復存在,但它的繼任者Bourne shell保留了相同的語法(儘管它的手冊頁只提到了|
)。ash、bash 和 ksh 等後繼 shell 只能理解
|
為管道字元。您不會在開源 unix 變體上找到真正的 Bourne shell,因為很長一段時間都沒有 Bourne shell 的開源版本。(我認為 OpenSolaris 包括一個,但它沒有被其他地方採用,因為到那時它已經被新的實現長期淘汰了)。Single Unix 規範沒有提及特殊字元,這
^
實際上意味著 POSIX shell 應該按字面意思解釋它¹。我認為從來沒有完全符合 POSIX 標準的 Bourne shell 變體(只有獨立的實現)。
^
啟用該選項時在 zsh 中是特殊的extendedglob
,但在其 sh 兼容模式下則沒有。在其預設模式下,它在許多方面偏離了 POSIX。
^
為了清楚起見,我建議在正則表達式中引用。引用腳本中的正則表達式,無論其中出現什麼字元。¹除了作為萬用字元模式中括號表達式的第一個字元,其中
!
是標準否定字元,但實現也可以以^
相同的方式解釋。