不带引号的文件中哪些字符需要转义?

不带引号的文件中哪些字符需要转义?

我有基于浏览器的 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 允许这样做。这是使用单引号而不是反斜杠的另一个原因。

相关内容