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,
наб

Attachment: signature.asc
Description: PGP signature

Reply via email to