Hi! On Tue, Dec 20, 2022 at 01:09:47AM +0100, Vincent Lefevre wrote: > On 2022-12-19 23:46:48 +0100, наб wrote: > > As in one /can/ accept anything in the name (XBD, 3.10 Alias Name), > > but /must not/ expand aliases when the word is in any way quoted. > I would say that "\mv" is a quoted version of "mv", but an unquoted > version of "\mv". Well, when turning tokens into words, quotes are removed (XCU, 2.6), so.
> I suspect that the POSIX text is based on the fact than normally, > alias names cannot contain quote mechanisms. Otherwise it is rather > ambiguous. Not really. The only bit affected is that XCU, alias, STDOUT only requires that the value be quoted for reinput to the shell, and not the name; naturally if you accept more than the minimum (XBD, 3.10 Alias Name: [a-zA-Z!^,@]+), then you should quote the name to preserve this property as well. > Note also that > https://pubs.opengroup.org/onlinepubs/9699919799/utilities/alias.html > says: "An alias definition provides a string value that shall replace > a command name when it is encountered", with no restrictions on words > with quoting mechanism. Yes, and it includes a link to the shell tokenisation rules, which are actually normative w.r.t. when alias substitution happens: After a token has been categorized as type TOKEN (see Section 2.10.1), including (recursively) any token resulting from an alias substitution, the TOKEN shall be subject to alias substitution if: * the TOKEN does not contain any quoting characters, * the TOKEN is a valid alias name (see XBD Section 3.10), * an alias with that name is in effect, * the TOKEN did not either fully or, optionally, partially result from an alias substitution of the same alias name at any earlier recursion level, and * the TOKEN could be parsed as the command name word of a simple command (see Section 2.10), based on this TOKEN and the tokens (if any) that preceded it, but ignoring whether any subsequent characters would allow that, (Issue 8 Draft 2.1, cf. https://www.austingroupbugs.net/view.php?id=953; Issue 7 says the same thing about the quoting bits but less eloquently.) > No, alias substitution is done before quoting mechanisms are involved. > Otherwise one would get an error in the following: > > $ alias 'foo=\echo ab' > $ alias > foo='\echo ab' > $ foo > ab No? Again, XCU, 2.3.1 Alias Substitution: When a TOKEN is subject to alias substitution, the value of the alias shall be processed as if it had been read from the input instead of the TOKEN, with token recognition (see Section 2.3) resuming at the start of the alias value. When the end of the alias value is reached, the shell may behave as if an additional <space> character had been read from the input after the TOKEN that was replaced. If it does not add this <space>, it is unspecified whether the current token is delimited before token recognition is applied to the character (if any) that followed the TOKEN in the input. "foo\n" is read, partially tokenised as as [<foo>, ...], this satisfies the conditions above, tokenisation restarts on "\\echo ab\n", this yields [<\echo>, ...], this contains a quote, so tokenisation continues for [<\echo>, <ab>]; <\echo> isn't a reserved token, so XCU 2.10.2 pt. 7a doesn't apply so pt. 1 sentence 2 applies and word expansion occurs, yielding a simple_command consisting of cmd_name=(echo) cmd_suffix=(ab) (i ran out of markup for WORDs, parens must do). "echo" is executed with single parameter "ab". (Roughly; the syntax is mind-numbing, and there's so many steps that do nothing here. You get the point.) > > In sh and ksh compatibility mode, which zsh apparently has, zsh does > > behave like dash/POSIX (allows anything in the name, doesn't expand > > aliases when quoted)). > I also suspect that if aliases with backslashes have been defined > before zsh is put in sh/ksh compatibility mode, like that: > /// > then such aliases must be ignored in sh/ksh compatibility mode to > avoid some surprises. This can explains the zsh behavior in alias > substitution. Well, I wouldn't say "ignored". The Zsh Language just applies a different set of rules to alias expansion (effectively, it provides aliases for TOKENs instead of WORDs; this is weird and confusing, since you /never/ observe TOKENs directly like this and you /execute/ WORDs; frankly, the decision to not do quote removal in this context is /baffling/, but, y'know. zsh.). Under sh emulation it applies the correct rules. In both languages all characters are valid parts of an alias. > However, in sh/ksh compatibility mode, I would rather expect > alias '\mv=echo ab' > to give an error, as the alias name is invalid in this context. Why? Again, XBD, 3.10 Alias Name: Implementations may allow other characters within alias names as an extension. You directly observe that a backslash is a valid part of an alias name because alias didn't exit >0. It's just fundamentally impossible for it to ever actually get substituted. This matches dash. Many characters aren't valid parts of the alias name under ksh and bash (and mksh), even those that would be fine to substitute (under bash that's the slash). That's fine, too. Best, наб
signature.asc
Description: PGP signature