將我們的注意力僅限於bash
, 在這個答案Stack Overflow 上有如下報道。
extglob
是一個使用的標誌由解析器。函數、複合命令等。在執行之前被完整解析。因此,extglob
必須在解析該內容之前設定;在執行時但在解析時間之後設定它不會對先前解析的內容產生任何影響。這也是為什麼您不能
shopt -s extglob; ls !(*.txt)
作為單行運行(extglob
以前未設定時),但必須在兩個命令之間有一個換行符。
但是,對於其他 shell 選項而言,情況並非如此。例如考慮以下情況。
$ ls -a
. .. .hiddenFile file1 file2 file3
$ shopt dotglob
dotglob off
$ echo *
file1 file2 file3
$ shopt -s dotglob; echo *
.hiddenFile file1 file2 file3
是否在某處記錄了解析器使用哪些 shell 選項extglob
,因此無法在使用它們的群組命令中啟用它們?
在裡面shopt
bash
手冊中的頁面似乎沒有提及上述行為。
答案1
是否在某處記錄了解析器(如 extglob)使用哪些 shell 選項,因此無法在使用它們的群組命令中啟用?
很難證明是否定的,但我懷疑是否有一個全面的清單。
我發現影響解析的如下,可能還有其他:
extglob
-- 改變括號的含義,否則括號是特殊字符expand_aliases
-- 別名在處理的早期就擴展了extquote
-- 更改了一些引用的含義interactive_comments
#
-- 更改單字開頭的意思。
有些compat*
選項可能也有類似的效果,但我會把測驗留給更感興趣的人。
另一方面,像dotglob
, failglob
and 這樣的東西globstar
只影響 glob 的結果,而不影響它的解析方式。
關於extglob
,像這樣的命令列無論帶set 還是不帶 set 都!(foo)
有效。extglob
有了它,它就是一個匹配所有檔案的 glob foo
,但是如果沒有它,它就是一個運行命令的子 shell foo
,返回值相反。
請注意,在實踐中,這不應該成為問題。在腳本中,您可以將shopt
命令放在自己的一行中,因此解析中的變更會毫無問題地影響下一行。在單行程式碼中,您可以-O
在命令列上使用該選項,例如在 中bash -O extglob -c 'echo !(foo)'
,擴充的 glob 可以運作。