为什么 `echo -e "\\\SOME_TEXT"` 只显示一个反斜杠?

为什么 `echo -e "\\\SOME_TEXT"` 只显示一个反斜杠?

有人能解释一下 Linux shell 中字符转义的幕后情况吗?我尝试了以下操作,并在 Google 上搜索了很多,但还是没能理解发生了什么(以及如何发生):

root@sv01:~# echo -e "\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\\\ Hello!"
\ Hello!
root@sv01:~# echo -e "\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\\\ Hello!"
\\ Hello!
root@sv01:~# echo -e "\\\\\\\\\ Hello!"
\\\ Hello!
root@sv01:~# echo -e "\n Hello!"

 Hello!
root@sv01:~# echo -e "\\n Hello!"

 Hello!
root@sv01:~# echo -e "\\\n Hello!"
\n Hello!

我完全迷失了,例如,为什么三个反斜杠只会产生一个反斜杠?我期望:前两个将被转义为一个,第三个将找不到任何可转义的内容,因此它将保留为斜线(第一个实验中的线),但实际发生的情况是,第三个消失了。
为什么我从四个中得到一个反斜杠\\\\ Hello我希望每对都会给出一个反斜杠 -> 两个反斜杠。

为什么在最后一种情况下我需要三个反斜杠才能转义 \n?转义的背景下发生了什么?它与\\n案例有何不同?

我很感激对前面几行发生的事情的任何解释。

答案1

这是因为bash和 的echo -e结合。从man 1 bash

未加引号的反斜杠 ( \) 是转义字符。它保留后面下一个字符的字面值,但 除外<newline>。[…]

将字符括在双引号中会保留引号内所有字符的字面值,但以下字符除外:、、、$[ …] 反斜杠仅当后面跟着以下字符之一时才保留其特殊含义:、、、、或。`\$`"\<newline>

要点是:双引号反斜杠并不总是特殊的。

一般来说,有各种实现echo,它是内置的bash;这里重要的是这种行为:

如果-e有效,则识别以下序列:
\\
反斜杠
[…]
\n
换行

现在我们可以解码:

  1. echo -e "\ Hello!"– 对 来说没什么特别的bash,对 来说没什么特别的echo\留下来。
  2. echo -e "\\ Hello!"– 第一个\告诉从字面上bash看待第二个;获取并按上述方式操作。\echo\ Hello!
  3. echo -e "\\\ Hello!"– 第一个\告诉从字面上bash看待第二个\echo得到\\ Hello!并且(因为-e)它识别\\\
  4. echo -e "\\\\ Hello!"– 第一个\告诉bash要从字面上看待第二个\;第三个告诉要从字面上看待第四个;echo得到\\ Hello!并且(因为-e)它识别\\\
  5. echo -e "\\\\\ Hello!"– 第一个\告诉bash要按字面意思对待第二个\;第三个告诉要按字面意思对待第四个;最后一个并不特殊;echo得到\\\ Hello!并且(因为-e)它将首字母识别\\\,最后一个\保持不变。

依此类推。如您所见,最多四个连续的反斜杠会给出结果 1。这就是为什么您需要 (至少) 九个反斜杠才能得到 3。9=4+4+1。

现在有\n

  1. echo -e "\n Hello!"– 没有什么特别的bash,echo 获取相同的字符串并且(因为-e)它将其解释\n为换行符。
  2. echo -e "\\n Hello!"bash解释\\\echo得到\n Hello!并且结果与上面相同。
  3. echo -e "\\\n Hello!"bash将首字母解释\\\echo得到\\n Hello!并且(因为-e)它解释为需要打印的\\文字。\

'如果有"(由于bash行为不同)或者没有-e(由于行为不同),结果会有所不同echo

相关内容