Why do backslashes prevent alias expansion?

自闭症网瘾萝莉.ら 提交于 2019-11-29 00:43:01

问题


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.


回答1:


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:

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



回答2:


Just for completion, here's yet another way to suppress alias & function lookups (by clearing the entire shell environment for a single command):

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



回答3:


\ls only quotes the first character rather than the whole word. It's equivalent to writing 'l's.

You can verify it like this:

$ touch \?l
$ \??
bash: ?l: command not found

If \?? quoted the whole word it would say ?? not found rather than ?l not found.

I.e. it has the same effect as:

$ '?'?
bash: ?l: command not found

rather than:

$ '??'
bash: ??: command not found


来源:https://stackoverflow.com/questions/6162903/why-do-backslashes-prevent-alias-expansion

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!