我有基于浏览器的 shell/终端来执行 bash 命令,并且我正在转义空格,但事实证明括号也需要转义。对于不在引号中的文件名,还需要转义哪些其他字符?
答案1
简单的解决方案是在开头放置一个单引号 ( '
),在末尾放置另一个单引号,然后将'
文件名中的每个字符替换为 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),至少在某些情况下您需要引用以下字符。
- 空白(空格、制表符、换行符——记住换行符不能用反斜杠引用)。
!
——历史扩展。"
— shell 语法。#
— 注释在前面有空格时开始; zsh 通配符。$
— shell 语法。&
— shell 语法。'
— shell 语法。(
— 即使在单词中间:ksh 扩展 glob(也可在 bash 和 zsh 中使用); zsh 通配符。)
(看(
)*
— sh 通配符。,
— 仅在大括号内展开。;
— shell 语法。<
— shell 语法。=
- 在命令名称中(而不是在参数中),如果它看起来像一个赋值。另外,在 zsh 中,当它位于文件名的开头时(通过 PATH 查找进行文件名扩展)。>
— shell 语法。?
— sh 通配符。[
— sh 通配符。\
— shell 语法。]
——你可能不加引号就可以逃脱惩罚。^
——历史扩展; zsh 通配符。`
— shell 语法。{
— 支撑扩张。|
— shell 语法。}
— 需要在 zsh 中转义,当没有匹配的左大括号时,其他 shell 会更宽松。~
— 主目录位于文件名开头时的扩展; zsh 通配符;当它是最后一个角色时总是安全的。
有时更多的字符可能需要特殊处理:
-
对 shell 来说并不特殊,但当它位于命令参数的开头时,它表示一个选项。它不能用引号保护,因为特殊处理是在命令中,而不是在 shell 中。要保护以 开头的文件名-
,您可以在它前面加上./
—— 这样它仍然是同一个文件,但参数不再以 开头-
。.
本身并不特殊,但*
默认情况下,点文件被排除在 glob 之外。:
对于 shell 来说并不特殊,但有些命令会对其进行特殊解析,例如指示远程文件 (hostname:filename
)。请查阅该命令的文档,了解如何处理包含冒号的文件名。
1除非用户配置了备用历史扩展字符。有些 shell 允许这样做。这是使用单引号而不是反斜杠的另一个原因。