bash 中不能使用感叹号 (!)?

bash 中不能使用感叹号 (!)?

!我正在尝试使用curl 命令访问路径中带有感叹号( ) 的http url 。例如:

curl -v "http://example.org/!287s87asdjh2/somepath/someresource"

控制台回复bash: ... event not found

这是怎么回事?以及转义感叹号的正确语法是什么?

答案1

感叹号是的一部分历史扩展在bash中。要使用它,您需要它用单引号括起来(例如'http://example.org/!132':)。

\您可以尝试在字符前使用反斜杠 ( ) 直接转义它(例如: "http://example.org/\!132")。然而,尽管感叹号之前的反斜杠确实阻止了历史扩展,但反斜杠是不是在这种情况下,某些外壳上会被删除。因此最好使用单引号,这样您就不会将文字反斜杠curl作为 URL 的一部分传递。

答案2

除了丹尼尔给出的答案之外,如果您不使用它,您也可以简单地完全关闭历史扩展:

set +H

或者

set +o histexpand

(后者也在 中工作zsh,其中histexpand是 bash 兼容性选项的替代名称banghist)。

在历史扩展起源的 (t)csh 中,您可以通过将空字符串分配给变量来禁用它$histchars

set histchars = ''

或者:

set histchars

(不通过unset histchars

这也适用于 bash 和 zsh,这两个 shell 复制了该功能,尽管语法是:

histchars=

那里。

请注意bash(与 (t)csh 或 zsh 相反)不会忽略$histchars在环境中找到的变量,因此请注意导出该变量时可能出现的后果。

答案3

我个人会使用单引号,但为了完整起见,我还会注意到,因为它是一个 URL,所以您可以将!as编码%21,例如curl -v http://example.org/%21132

答案4

我遇到了同样的问题,我的简单解决方案是使用变量:

E=!  
curl -v "http://example.org/${E}287s87asdjh2/somepath/someresource"

这里的简单性在于 (1) 它可以跨 shell 和命令移植 (2) 不需要了解转义语法和 ASCII 代码。

相关内容