2011-05-28 43 views
20

在我的問題的第一部分,我將提供一些背景信息作爲社區的 服務。第二部分包含實際問題。反斜槓爲什麼會阻止別名擴展?

第一部分

假設我已經創建了以下的別名:

alias ls='ls -r' 

我知道如何暫時unalias(即覆蓋此別名)在以下 方式,使用:

1)命令的完整路徑名:/bin/ls

2)命令替換:$(which ls)

3)命令內置:command ls

4)雙引號:"ls"

5)單引號:'ls'

6)反斜線字符: \ls

情況1很明顯,情況2只是一種變化。 case 3中的命令builtin被設計爲忽略shell函數,但顯然它也可用於規避別名。最後,例4和5是與兩個POSIX standard (2.3.1)一致:

「所產生的被識別 是一個 簡單命令的命令名字應進行檢查,以 確定它是否是一個不帶引號的字, 有效的別名。「

Bash Reference Manual (6.6)

「每個簡單 命令的第一個字,如果沒有引用的,被檢查以 看它是否有別名」。

第二部分

這裏的問題:爲什麼案件6 認爲引述字(說\ls覆蓋別名)?根據這個問題的風格,我正在尋找對「官方」文檔的參考。

文檔說反斜槓只逃脫以下 字符,而不是單引號和雙引號,該引號字符的 序列。POSIX standard (2.2.1)

「未引述應 保存 以下字符的字面意義反斜槓,與 異常的<新行>」

Bash Reference Manual (3.1.2.1)

」未加引號的反斜槓'\'是 Bash轉義字符。它保留 字面值接下來的 字符的值, 例外的換行符。「

(順便說一句,是不是有點大材小用「而隨後的字符」?)

一個可能的答案可能是,這種情況並非特殊:它是 類似幾ANSI-C引用中的例子,例如\nnn。然而,這仍然是 轉義單個字符(八位字符的值是八進制 值nnn),而不是一個字符序列。

+0

只是注意:第6個不同於第5個:第5個繞過函數AND別名,而'\ ls'將(在bash中)繞過別名,而不是同名的函數。即:'alias ls ='echo「aliased」';函數ls {echo「function」; }; ls; \ ls;命令ls':第一個(ls)將顯示「aliased」,第二個(\ ls)只會繞過別名,因此顯示「function」,第三個(命令ls)顯示常規ls的輸出 – 2013-09-10 17:30:50

+0

這是一個很棒的問題,但沒有任何解釋似乎可以澄清我對此事的任何困惑。 @ alexandros-gezerlis,如果你已經能夠理解其中的原因,你能否爲我(家裏的人)拼出來? – harperville 2016-12-21 19:11:45

+0

@OlivierDulac 5至少在GNU bash中沒有繞過函數4.3.11 – jarno 2017-06-11 11:25:24

回答

5

歷史上,由POSIX維護,引用該詞的任何部分導致整個單詞被認爲是引用的功能和別名擴展的目的。它也適用於引用結束令牌立即文檔:

cat << \EOF 
this $text is fully quoted 
EOF 
+0

謝謝。我編輯了這個問題(第二部分的第一段)來澄清我錯誤地認爲是顯而易見的事情:我希望有具體的引用。 – 2011-05-28 16:48:12

+0

另外,我剛剛注意到POSIX 2.7.4在這裏的文檔中明確指出了轉義的情況:「如果引用了單詞中的任何字符,則通過對單詞執行引用刪除來形成分隔符」。然而,在關於令牌識別的一般部分(POSIX 2.3)中明確指出,這裏的文件是特殊的:「這些行應使用兩種主要模式進行解析:普通令牌識別和對這裏文件的處理。」 – 2011-05-28 17:02:10

+0

@Alexandros:這些都有點模棱兩可。在第一次引用之後,你想稍微閱讀2.7.4節的內容:「如果沒有引用單詞中的任何字符,那麼這裏的文檔的所有行都應擴展用於參數擴展,命令替換和算術擴展。在這種情況下,輸入中的反斜槓表現爲雙引號內的反斜槓(參見雙引號),但雙引號字符(''')不應該在here-document中專門處理,除非雙引號-quote出現在「$()」,「'」或「$ {}」中。「 – geekosaur 2011-05-28 18:05:37

5

剛剛完成,這裏是另一種方式來抑制別名&功能查找(通過清除整個shell環境單個命令):

# cf. http://bashcurescancer.com/temporarily-clearing-environment-variables.html 
env -i ls 
相關問題