如何躲过历史扩展感叹号!在双引号字符串中? [英] How to escape history expansion exclamation mark ! inside a double quoted string?
问题描述
命令替换对于令人惊讶的行为不是必需的,尽管它是最常见的用例.同样的问题只适用于 echo "'!b'"
the command substitution is not necessary for the surprising behavior, although it is the most common use case. The same question applies to just 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 指出). - In the last example, what is the best way to escape the
!
? - Why was it not escaped even if I used single quotes, while
echo "$(echo '$b')"
was? What is the difference between!
and$
? - Why was does
echo $(echo '!b')
(no quotes) work? (pointed by @MBlanc). set +H
因为我之后需要set -H
来维持 shell 状态set +H
as I would needset -H
afterwards to maintain shell state
我宁愿不这样做:
反斜杠转义,因为我需要为每个 !
设置一个,而且它必须在引号之外:
backslash escapes, because I need one for every !
and it has to be outside the quotes:
echo "$(echo '!a')"
# '!a'.
# No good.
echo "$(echo 'a '!' b '!' c')"
# a ! b ! c
# Good, but verbose.
echo $(echo '!b')
(无引号),因为命令可能返回空格.
echo $(echo '!b')
(no quotes), because the command could return spaces.
版本:
bash --version | head -n1
# GNU bash, version 4.2.25(1)-release (i686-pc-linux-gnu)
推荐答案
在上一个例子中,
echo "$(echo '!b')"
感叹号不是单引号.因为历史扩展发生在解析过程的早期,单引号只是双引号字符串的一部分;解析器尚未识别命令替换以建立新的上下文,其中单引号将引用运算符.
the exclamation point is not single-quoted. Because history expansion occurs so early in the parsing process, the single quotes are just part of the double-quoted string; the parser hasn't recognized the command substitution yet to establish a new context where the single quotes would be quoting operators.
要修复,您必须暂时关闭历史扩展:
To fix, you'll have to temporarily turn off history expansion:
set +H
echo "$(echo '!b')"
set -H
这篇关于如何躲过历史扩展感叹号!在双引号字符串中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!