如果是,什么时候?谁能解释一下吗?
echo -e \tr\t\e\\re\e
#eete
echo \tr\t\e\\re\e
#trte\ree
答案1
这与 shell 如何解析命令有关,而与 shellecho
本身关系不大。举你的第一个例子:
echo -e \tr\t\e\\re\e
由于反斜杠出现在引号之外,因此 shell 会将这些反斜杠解释为转义标记,从而删除反斜杠后面的字符的任何特殊(对于 shell)含义。 shell 将这行代码解析为三个单词:echo
、-e
和trte\ree
。第一个单词成为要执行的命令,而后两个单词成为其参数;解析后的参数是唯一echo
看到的东西。因为-e
给出了该选项,所以该echo
命令将照常解释转义,但在字符串中trte\ree
,因为这是 shell 传递给它的内容。
将第二个参数放在单引号中可以防止 shell 解释该\
字符,从而允许它逐字传递echo
。因此:
echo -e '\tr\t\e\\re\e'
shell 将echo
使用第一个参数-e
和第二个参数进行调用\tr\t\e\\re\e
。现在需要echo
解释所有转义序列。
答案2
\
是shell 的引用运算符。\x
就像'x'
它删除了特殊含义x
(除非x
它删除了换行符)。
所以:
echo -e \tr\t\e\\re\e
就好像:
echo -e 't'r't''e''\'re'e'
t
, r
,e
在 shell 语法中都不是特殊的。\
是那里唯一特别的一个。所以本质上,这相当于:
echo -e trte'\'ree
或者:
echo -e 'trte\ree'
您的echo
实现似乎是接受一个-e
选项来告诉它解释 ANSI C 转义序列的实现之一,因此它转换\r
为回车符,这是一个控制字符,当发送到终端时告诉它将光标移回到行的开头,所以你会看到eete
(trte
部分被 覆盖ee
),而trte\ree
没有。
如果您希望将包含的参数\tr\t\e\\re\e
传递给echo -e
,以便它输出<TAB>r<TAB><ESC>\e<ESC>
,则需要引用/转义反斜杠字符,以便 shell 不会将它们解释为引用运算符:
echo -e '\tr\t\e\\re\e'
echo -e \\tr\\t\\e\\\\re\\e
echo -e "\\tr\\t\\e\\\\re\\e" # (\ is still special within "..." to escape
# the few characters that are still special
# to the shell within double quotes)
echo -e $'\\tr\\t\\e\\\\re\\e' # (\ is not a quoting operator in $'...'
# but has its own special meaning there
# similar to that it has for echo)
或者你可以这样做:
echo $'\\tr\\t\\e\\\\re\\e'
这次, , ,分别$'...'
扩展为 TAB, ESC, CR, \ ,因此接收一个包含 的参数,如果没有,您将按原样显示(尽管请注意,并非所有实现都如此,因为许多实现都解释为默认情况下(有些可以用 禁用))。\t
\e
\r
\\
echo
<TAB>r<TAB><ESC>\e<ESC>
-e
echo
echo
-e
-E