Bash
哪些字元需要在不帶引號的文件中轉義?
我有基於瀏覽器的 shell/終端,它執行 bash 命令並且我正在轉義空格,但事實證明括號也需要轉義。對於不在引號中的文件名,還需要轉義哪些其他字元?
簡單的解決方案是在開頭放一個單引號 (
'
),在結尾放一個單引號,並將'
文件名中的每個字元替換為 4 字元序列'\''
。所有字元在單引號字元串中都失去了它們的特殊含義,除了'
標記字元串結尾的字元本身。該序列'\''
結束單引號文字,緊隨其後的是帶引號的單引號,並打開一個新的單引號文字。因此文件名This file's name has some weird characters! Will you manage to escape them?
可以引用如下:
somecommand 'This file'\''s name has some weird characters! Will you manage to escape them?'
雙引號有更複雜的轉義規則,如果啟動歷史替換,則不允許您包含驚嘆號
!
,因此我不會進一步考慮它們。另一種方法是使用反斜杠保護字元。這適用於除換行符以外的每個字元;對於換行符,將其放在單引號(或雙引號)內是唯一的解決方案。如果您想最小化反斜杠的數量以向使用者呈現引用的名稱,您可以將其限制在需要反斜杠的地方;但是,您省略的反斜杠越多,您就越有可能忘記需要的反斜杠。字母、數字和非 ASCII 字元總是可以的¹。不確定時引用空格和標點符號。
使用典型的 shell(ksh、bash 或 zsh),至少在某些情況下需要引用以下字元。
- 空格(空格、製表符、換行符——記住換行符不能用反斜杠引用)。
!
——歷史擴展。"
— 外殼語法。#
— 註釋以空格開頭;zsh 萬用字元。$
— 外殼語法。&
— 外殼語法。'
— 外殼語法。(
— 即使在一個單詞的中間:ksh 擴展 glob(也可用於 bash 和 zsh);zsh 萬用字元。)
(見(
)*
— sh 萬用字元。,
— 僅在大括號內展開。;
— 外殼語法。<
— 外殼語法。=
— 在 zsh 中,當它位於文件名的開頭時(使用 PATH 查找的文件名擴展)。>
— 外殼語法。?
— sh 萬用字元。[
— sh 萬用字元。\
— 外殼語法。]
——你可以不引用它而僥倖逃脫。^
— 歷史擴展;zsh 萬用字元。{
— 大括號擴展。|
— 外殼語法。}
— 需要在 zsh 中轉義,當沒有匹配的左大括號時,其他 shell 會更寬鬆。~
— 位於文件名開頭的主目錄擴展;zsh 萬用字元;當它是最後一個字元時總是安全的。更多字元有時可能需要特殊處理:
-
對 shell 來說不是特殊的,但是當它位於命令參數的開頭時,它表示一個選項。它不能用引號保護,因為特殊處理在命令中,而不是在 shell 中。要保護以 開頭的文件名-
,您可以./
在它前面加上 - 這樣它仍然是同一個文件,但參數不再以開頭-
。.
本身並不特殊,但*
預設情況下,點文件被排除在 glob 之外。:
對 shell 來說不是特殊的,但有些命令會專門解析它,例如指示遠端文件 (hostname:filename
)。請查閱命令的文件以了解如何處理包含冒號的文件名。¹除非使用者配置了備用歷史擴展字元。一些 shell 允許這樣做。這是使用單引號而不是反斜杠的另一個原因。