无法理解反引号内反斜杠的非明显用法 [英] Trouble understanding the non-obvious use of backslash inside of backticks

查看:82
本文介绍了无法理解反引号内反斜杠的非明显用法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了包括bash手册在内的大量页面,但是仍然发现反斜杠的非显而易见"用法令人困惑.

I have read a ton of pages including the bash manual, but still find the "non-obvious" use of backslashes confusing.

如果我这样做:

echo \*

它会打印一个星号,这是正常现象,因为我正在将星号转义为文字.

it prints a single asterisks, this is normal as I am escaping the asterisks making it literal.

如果我这样做:

echo \\*

它打印 \ * 这似乎很正常,第一个反斜杠转义了第二个斜杠.

it prints \* This also seems normal, the first backslash escapes the second.

如果我这样做

echo `echo \\*`

它打印目录的内容.但是在我看来,它应该打印与 echo \\ * 相同的内容,因为当替换并传递给echo时.我知道这是每个人都在谈论反斜杠的非显而易见的用法,但我仍在努力理解为什么会这样.

It prints the contents of the directory. But in my mind it should print the same as echo \\* because when that is substituted and passed to echo. I understand this is the non-obvious use of backslashes everyone talks about, but I am struggling to understand WHY it happens.

bash手册还说

使用老式的反引号形式的替换时,反斜杠保留其字面意思,除非后面跟有"$",`"或"\".

When the old-style backquote form of substitution is used, backslash retains its literal meaning except when followed by ‘$’, ‘`’, or ‘\’.

但是它并没有定义反斜杠的字面意思"是什么.它是转义字符,连续字符还是仅是反斜杠字符?

But it doesn't define what the "literal meaning on backslash" is. Is it as an escape character, a continuation character, or just literally a backslash character?

此外,它说保留了它的字面意思,除非后面跟有....因此,当后面跟着这三个字符之一时,它的作用是什么?它只会逃避这三个字符吗?

Also, it says it retain it's literal meaning, except when followed by ... So when it's followed by one of those three characters what does it do? Does it only escape those three characters?

推荐答案

这主要是出于历史考虑,因为`...`命令替换已由更清洁的 $(代替)...)形式.禁止新脚本使用反引号.

This is mostly for historical interest since `...` command substitution has been superseded by the cleaner $(...) form. No new script should ever use backticks.

这是您评估 $(command)替换的方式

  1. 运行命令

这是您评估`string` 命令替换的方式:

Here's how you evaluate a `string` command substitution:

  1. 确定字符串的范围,从开始反引号到结束未转义反引号(如果此反引号在字符串文字内,则行为未定义:外壳通常会将其视作文字反引号或封闭反引号,具体取决于其解析器实现)
  2. 通过除去三个字符dollar,反引号或反斜杠之一之前的反斜杠来对字符串进行转义.然后,将以下字符逐字插入命令中.反斜杠后跟任何其他字符将被保留.
    • 例如 Hello \\ World 将变为 Hello \ World ,因为 \\ 被替换为 \
    • Hello \ World 也将变为 Hello \ World ,因为反斜杠后面是三个字符之一之外的字符,因此保留了原义反斜杠
    • \\\ * 将成为 \\ * ,因为 \\ 将仅成为 \ (自反斜杠是三个中的一个), \ * 将保持为 \ * (因为星号不是)
  1. Determine the span of the string, from the opening backtick to the closing unescaped backtick (behavior is undefined if this backtick is inside a string literal: the shell will typically either treat it as literal backtick or as a closing backtick depending on its parser implementation)
  2. Unescape the string by removing backslashes that come before one of the three characters dollar, backtick or backslash. This following character is then inserted literally into the command. A backslash followed by any other character will be left alone.
    • E.g. Hello\\ World will become Hello\ World, because the \\ is replaced with \
    • Hello\ World will also become Hello\ World, because the backslash is followed by a character other than one of those three, and therefore retains its literal meaning of just being a backslash
    • \\\* will become \\* since the \\ will become just \ (since backslash is one of the three), and the \* will remain \* (since asterisk is not)

因此要评估 echo`echo \\ *`:

  1. 确定字符串的跨度,在这里 echo \\ *
  2. 根据反引号引用规则对其进行转义: echo \ *
  3. 将其评估为命令,该命令运行echo以输出文字 *
  4. 由于替换结果未引用,因此输出将经历:
  1. Determine the span of the string, here echo \\*
  2. Unescape it according to the backtick quoting rules: echo \*
  3. Evaluate it as a command, which runs echo to output a literal *
  4. Since the result of the substitution is unquoted, the output will undergo:
  1. 分词: * 变为 * (因为它只是一个单词)
  2. 每个单词的路径名扩展,因此 * 成为 bin Desktop Downloads Photos public_html 根据当前目录中的文件
  3. 请特别注意,这与将backtick命令替换为输出并重新运行结果不同.例如,我们没有考虑输出中的转义,引号和扩展,而基于文本的简单宏扩展将具有转义,引号和扩展.
  1. Word splitting: * becomes * (since it's just one word)
  2. Pathname expansion on each of the words, so * becomes bin Desktop Downloads Photos public_html according to files in the current directory
  3. Note in particular that this was not the same as replacing the the backtick command with the output and rerunning the result. For example, we did not consider escapes, quotes and expansions in the output, which a simple text based macro expansion would have.

  • 将每个参数作为参数传递给下一个命令(也作为回显): echo bin桌面下载照片public_html
  • 结果是当前目录中的文件列表.

    The result is a list of files in the current directory.

    这篇关于无法理解反引号内反斜杠的非明显用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆