为什么反斜杠会阻止别名扩展?
在我的问题的第一部分,我将提供一些背景信息作为 服务社区。第二部分包含实际问题。
第一部分
假设我已经创建了以下别名:
alias ls='ls -r'
我知道如何在以下内容中暂时取消别名(即覆盖此别名) 方式,使用:
1) 命令的完整路径名:/bin/ls
2) 命令替换:$(which ls)
3) 内置命令:命令 ls
4) 双引号:"ls"
5) 单引号:'ls'
6) 反斜杠字符:\ls< /code>
情况 1 是显而易见的,而情况 2 只是一个变体。案例 3 中的内置命令旨在忽略 shell 函数,但显然它也适用于规避别名。最后,情况 4 和 5 均符合 POSIX 标准 (2.3.1 ):
“已识别的结果单词 是 a 的命令名称词 应检查简单命令 确定它是否是未引用的, 有效的别名。”
和 Bash 参考手册 (6.6) :
“每个简单的第一个单词 命令,如果未加引号,则检查为 看看它是否有别名。”
第二部分
问题是:为什么是情况 6(通过说 \ls
覆盖别名) 考虑过引用这个词吗?为了与这个问题的风格保持一致,我正在寻找对“官方”文档的引用。
文档说反斜杠只能转义以下内容 字符,而不是单引号和双引号,它们引用一个 字符序列。 POSIX 标准 (2.2.1):
“未引用的反斜杠应 保留字面值 以下字符,与 例外 a <换行符 >"
“不带引号的反斜杠 '\' 是 Bash 转义字符。它保留了 下一个的字面值 接下来的字符,带有 换行符除外。”
(顺便说一句,“后面的下一个字符”不是有点矫枉过正吗?)
一个可能的答案可能是这种情况并不那么特殊:它是 类似于 ANSI-C 引用中的一些情况,例如 \nnn
。然而,这仍然是 转义单个字符(值为八进制的八位字符 值 nnn),而不是字符序列。
In the first part of my question I will provide some background info as a
service to the community. The second part contains the actual question.
Part I
Assume I've created the following alias:
alias ls='ls -r'
I know how to temporarily unalias (i.e., override this alias) in the following
ways, using:
1) the full pathname of the command: /bin/ls
2) command substitution: $(which ls)
3) the command builtin: command ls
4) double quotation marks: "ls"
5) single quotation marks: 'ls'
6) a backslash character: \ls
Case 1 is obvious and case 2 is simply a variation. The command builtin in case 3 was designed to ignore shell functions, but apparently it also works for circumventing aliases. Finally, cases 4 and 5 are consistent with both the POSIX standard (2.3.1):
"a resulting word that is identified
to be the command name word of a
simple command shall be examined to
determine whether it is an unquoted,
valid alias name."
and the Bash Reference Manual (6.6):
"The first word of each simple
command, if unquoted, is checked to
see if it has an alias."
Part II
Here's the question: why is case 6 (overriding the alias by saying \ls
)
considered quoting the word? In keeping with the style of this question, I am looking for references to the "official" documentation.
The documentation says that a backslash only escapes the following
character, as opposed to single and double quotation marks, which quote a
sequence of characters. POSIX standard (2.2.1):
"A backslash that is not quoted shall
preserve the literal value of the
following character, with the
exception of a < newline >"
Bash Reference Manual (3.1.2.1):
"A non-quoted backslash ‘\’ is the
Bash escape character. It preserves
the literal value of the next
character that follows, with the
exception of newline."
(BTW, isn't "the next character that follows" a bit of overkill?)
A possible answer might be that this situation isn't that special: it is
similar to a few cases in ANSI-C quoting, e.g. \nnn
. However, that is still
escaping a single character (the eight-bit character whose value is the octal
value nnn), not a sequence of characters.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
从历史上看,并且由 POSIX 维护,出于函数和别名扩展的目的,引用单词的任何部分都会导致整个单词被视为被引用。它也适用于引用此处文档的结束标记:
Historically, and maintained by POSIX, quoting any part of the word causes the entire word to be considered quoted for the purposes of functions and alias expansion. It also applies to quoting the end token for a here document:
为了完整起见,这里还有另一种抑制别名和别名的方法。函数查找(通过清除单个命令的整个 shell 环境):
Just for completion, here's yet another way to suppress alias & function lookups (by clearing the entire shell environment for a single command):
\ls 仅引用第一个字符而不是整个单词。它相当于写“l”。
你可以这样验证:
If \??引用了它会说的整个词?未找到而不是?l 未找到。
即它具有与以下相同的效果:
而不是:
\ls only quotes the first character rather than the whole word. It's equivalent to writing 'l's.
You can verify it like this:
If \?? quoted the whole word it would say ?? not found rather than ?l not found.
I.e. it has the same effect as:
rather than: