echo \\* - bash 反斜杠转义行为,是否向后评估?

Wei*_*i Z 7 shell bash echo quoting escape-characters

所以在 bash 中,当我这样做时

echo \*
*
Run Code Online (Sandbox Code Playgroud)

这似乎是正确的,因为 * 被转义并按字面​​意思理解。

但我无法理解,当我这样做时

echo \\*
\*
Run Code Online (Sandbox Code Playgroud)

我认为第一个反斜杠逃脱了第二个反斜杠,因此两个反斜杠“\\”会在字面上给我一个“\”。和 * 后面带有它的特殊含义。我期待:

echo \\*
\file1 file2 file3
Run Code Online (Sandbox Code Playgroud)

答案摘要:由于 \ 是按字面意思echo \*理解的echo a*,因此将表现得与 一样,它将查找以字面量“a”开头的任何文件。

跟进问题,如果我想打印出来完全一样

\file1 file2 file3
Run Code Online (Sandbox Code Playgroud)

我应该使用什么命令?例如,如下所示,但我不想要空间

echo \\ * 
\ file1 file2 file3
Run Code Online (Sandbox Code Playgroud)

Mic*_*mer 8

如果当前目录中没有名称以反斜杠开头的文件,则这是预期行为。Bash扩展*以匹配任何现有的文件名,但是

如果模式与任何现有文件名或路径名都不匹配,则模式字符串应保持不变。

因为没有以 开头的文件名\,所以模式保持原样echo并被赋予参数\*。这种行为常常令人困惑,而其他一些 shell,例如zsh,则没有。您可以在 Bash 中使用 更改它,shopt -o failglob然后它会给出一个错误zsh并帮助您诊断问题而不是行为不端。

*?模式字符可以在任何地方这个词出现了,之前的字符和之后的字面匹配。这就是为什么echo \\*echo \\ *给出如此不同的输出:第一个匹配以\(并失败)开头的任何内容,第二个输出 a \,然后是所有文件名。


安全获得所需输出的最直接方法可能是使用printf

printf '\\'; printf "%s " *
Run Code Online (Sandbox Code Playgroud)

echo *在任何情况下,在带有-或包含\在其中的异常文件名的情况下都是不安全的。