If I do

        alias switch=case

then every shell I can find, processes

        switch foo in foo) echo ok;; esac

correctly (and writes "ok" to stdout).    Aside from that I
don't think we should really have aliases at all (not relevant
directly here), that is fine.

However if I want to do

        echo "$( switch foo in foo) echo ok;; esac )"

then XCU 2.2.3 (2.2 is "Quoting" 2.2.3 is "Double-Quotes") 
(lines 74718-22, Issue 7 TC2 - 2018 edition) says ...

    The input characters within the quoted string that are also enclosed
    between "$(" and the matching ')' shall not be affected by the
    double-quotes, but rather shall define that command whose output
    replaces the "$(...)" when the word is expanded. The tokenizing rules
    in Section 2.3, not including the alias substitutions in Section 2.3.1,
    shall be applied recursively to find the matching ')'.

The relevant part here being the "not including the alias substitutions
in Section 2.3.1".

With the exception of an old (and broken in many ways) version pf pdksh,
I cannot find any shell which obeys that restriction.   If we were to
not do alias substitutions, then the above should run the

        "switch foo in foo"

command (assuming there is some command called "switch" to run) as the 
')' that follows the second "foo" will terminate the command substitution,
then take whatever it generates on stdout (perhaps nothing), append
" echo ok;; esac )" to that, and then write that string to stdout.

No shells do that (with or without a message to stderr about switch
not found .. other than the alias, there is no "switch" command on my
system).

Not even the broken pdksh, which seems to match that ')' after the second
"foo" as terminating the command substitution, but then processes the
alias anyway (later) and cannot find a valid case statement within the
truncated command substitution, so generates a syntax error.

But perhaps that is actually what the standard says must happen - we
don't use the alias for finding the matching ')', but then do when
parsing the command inside.    That would be a recipe for disaster,
but if it is what old versions of ksh did/do then perhaps the standard
really is requiring that?   If so, it is time for a change, as nothing
relevant acts like that any more (not mksh, not ksh93, not bosh, ...)

On the other hand, if we avoid that "not including the alias substitution"
rule, by the simple expedient of not double quoting anything, as in

        echo $( switch foo in foo) echo ok;; esac )

we have much stranger results.

With this one, that old pdksh, plus ksh93 and bash, all give a syntax error,
';;' unexpected - indicating that they parsed the command substitution as
ending at the first ')' - which means they did not process the alias (which
this time clearly should be processed - it is part of the tokenisation
process which is required to locate the ')'.

All other shells I tested (including mksh, bosh, zsh, yash, and the ash
derived shells) processed this correctly (and give the same result for the
quoted and non-quoted cases ... the quotes here don't have any actual
purpose, nothing needs them, IFS does not contain 'o' or 'k').

Is this part of the text something that has already been revised?  If
so, which bug report (so I can see what it now says or will say), or if
we still have this strange prohibition on alias processing in command
substitutions, when (and only when) they appear within double quotes,
is there any reason anyone is aware of that it shouldn't be deleted?

While I am here, one more variation.  If I change that unquoted command
to be

        echo $( switch foo in (foo) echo ok;; esac )

(to change the way the parentheses balance, without changing the meaning)
then every shell prints "ok" to standard output.   Including the old pdksh.
The results are the same if this command substitution is double quoted.

kre

Reply via email to