2011-05-28 60 views
20

在我的问题的第一部分,我将提供一些背景信息作为社区的 服务。第二部分包含实际问题。反斜杠为什么会阻止别名扩展?

第一部分

假设我已经创建了以下的别名:

alias ls='ls -r' 

我知道如何暂时unalias(即覆盖此别名)在以下 方式,使用:

1)命令的完整路径名:/bin/ls

2)命令替换:$(which ls)

3)命令内置:command ls

4)双引号:"ls"

5)单引号:'ls'

6)反斜线字符: \ls

情况1很明显,情况2只是一种变化。 case 3中的命令builtin被设计为忽略shell函数,但显然它也可用于规避别名。最后,例4和5是与两个POSIX standard (2.3.1)一致:

“所产生的被识别 是一个 简单命令的命令名字应进行检查,以 确定它是否是一个不带引号的字, 有效的别名。“

Bash Reference Manual (6.6)

“每个简单 命令的第一个字,如果没有引用的,被检查以 看它是否有别名”。

第二部分

这里的问题:为什么案件6 认为引述字(说\ls覆盖别名)?根据这个问题的风格,我正在寻找对“官方”文档的参考。

文档说反斜杠只逃脱以下 字符,而不是单引号和双引号,该引号字符的 序列。POSIX standard (2.2.1)

“未引述应 保存 以下字符的字面意义反斜杠,与 异常的<新行>”

Bash Reference Manual (3.1.2.1)

”未加引号的反斜杠'\'是 Bash转义字符。它保留 字面值接下来的 字符的值, 例外的换行符。“

(顺便说一句,是不是有点大材小用“而随后的字符”?)

一个可能的答案可能是,这种情况并非特殊:它是 类似几ANSI-C引用中的例子,例如\nnn。然而,这仍然是 转义单个字符(八位字符的值是八进制 值nnn),而不是一个字符序列。

+0

只是注意:第6个不同于第5个:第5个绕过函数AND别名,而'\ ls'将(在bash中)绕过别名,而不是同名的函数。即:'alias ls ='echo“aliased”';函数ls {echo“function”; }; ls; \ ls;命令ls':第一个(ls)将显示“aliased”,第二个(\ ls)只会绕过别名,因此显示“function”,第三个(命令ls)显示常规ls的输出 – 2013-09-10 17:30:50

+0

这是一个很棒的问题,但没有任何解释似乎可以澄清我对此事的任何困惑。 @ alexandros-gezerlis,如果你已经能够理解其中的原因,你能否为我(家里的人)拼出来? – harperville 2016-12-21 19:11:45

+0

@OlivierDulac 5至少在GNU bash中没有绕过函数4.3.11 – jarno 2017-06-11 11:25:24

回答

5

历史上,由POSIX维护,引用该词的任何部分导致整个单词被认为是引用的功能和别名扩展的目的。它也适用于引用结束令牌立即文档:

cat << \EOF 
this $text is fully quoted 
EOF 
+0

谢谢。我编辑了这个问题(第二部分的第一段)来澄清我错误地认为是显而易见的事情:我希望有具体的引用。 – 2011-05-28 16:48:12

+0

另外,我刚刚注意到POSIX 2.7.4在这里的文档中明确指出了转义的情况:“如果引用了单词中的任何字符,则通过对单词执行引用删除来形成分隔符”。然而,在关于令牌识别的一般部分(POSIX 2.3)中明确指出,这里的文件是特殊的:“这些行应使用两种主要模式进行解析:普通令牌识别和对这里文件的处理。” – 2011-05-28 17:02:10

+0

@Alexandros:这些都有点模棱两可。在第一次引用之后,你想稍微阅读2.7.4节的内容:“如果没有引用单词中的任何字符,那么这里的文档的所有行都应扩展用于参数扩展,命令替换和算术扩展。在这种情况下,输入中的反斜杠表现为双引号内的反斜杠(参见双引号),但双引号字符(''')不应该在here-document中专门处理,除非双引号-quote出现在“$()”,“'”或“$ {}”中。“ – geekosaur 2011-05-28 18:05:37

5

刚刚完成,这里是另一种方式来抑制别名&功能查找(通过清除整个shell环境单个命令):

# cf. http://bashcurescancer.com/temporarily-clearing-environment-variables.html 
env -i ls