编辑:对于令人惊讶的行为,命令替换不是必需的,尽管它是最常见的用例。同样的问题只适用于 echo "'!b'"
b=a
# Enable history substitution.
# This option is on by default on interactive shells.
set -H
echo '!b'
# Output: '!b'
# OK. Escaped by single quotes.
echo $(echo '!b')
# Output: '!b'
# OK. Escaped by single quotes.
echo "$(echo '$b')"
# Output: '$b'
# OK. Escaped by single quotes.
echo "$(echo '!b')"
# Output: history expands
# BAD!! WHY??
- 在最后一个示例中,转义
!
的最佳方法是什么? - 为什么即使我使用单引号也没有转义,而
echo "$(echo '$b')"
是?!
和$
有什么区别? - 为什么
echo $(echo '!b')
(无引号)有效? (由@MBlanc 指出)。
我宁愿这样做没有:
set +H
因为之后我需要set -H
来保持 shell 状态反斜杠转义,因为每个
!
都需要一个反斜杠,而且它必须在引号之外:echo "$(echo '\!a')" # '\!a'. # No good. echo "$(echo 'a '\!' b '\!' c')" # a ! b ! c # Good, but verbose.
echo $(echo '!b')
(无引号),因为该命令可能会返回空格。
版本:
bash --version | head -n1
# GNU bash, version 4.2.25(1)-release (i686-pc-linux-gnu)
最佳答案
在你的最后一个例子中,
echo "$(echo '!b')"
感叹号不是单引号。因为历史扩展发生在解析过程的早期,所以单引号只是双引号字符串的一部分;解析器尚未识别命令替换以建立新的上下文,其中单引号将引用运算符。
要修复,您必须暂时关闭历史扩展:
set +H
echo "$(echo '!b')"
set -H
关于bash - 如何逃脱历史扩展感叹号!在双引号字符串中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22125658/