Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Comment (# char) behavior in the sub-shell

On Sat, 9 Sep 2017 19:33:59 +0300
Stanislav Seletskiy <s.seletskiy@xxxxxxxxx> wrote:
> zsh version: 5.4.2
> I'm heavy user of `#`-aliases, so I like to do stuff like `seq 1 10 #
> 9` to grep for `9` (`alias -g -- '#'='| grep'`).
> It works as expected when I'm entering command in interactive mode
> without sub-shell, like:
> `$ seq 1 10 # 9` — works well, I see only `9` in the output.
> But when I'm trying to use same alias in the sub-shell (e.g. inside
> `$()`), it doesn't work anymore:
> `$ echo $(seq 1 10 # 9)` — doesn't work, I see `1 2 3 ... 10` in the output.

I suspect this changed some versions ago now.  At some point we changed
the way we handled $(...) to parse it better.  Previously, we just
blindly treated it as a string when we first enountered it, reading it
in interactively until we got to a closing parenthesis.  That wasn't
actually the right thing to do, and crucially it failed where there was
a case statement in the old syntax where a pattern only has a closing
parenthesis and not an opening parenthesis.  So what we do now is parse
properly until the (right) closing parenthesis, but still store what we
parsed as a string for reading again when we execute the $(...).

It so happens we don't keep the expanded aliases from the original parse
in the string we later replay.  There is a test for just this case;
here it is:

 alias fooalias=barexpansion
 funcwithalias() { echo $(fooalias); }
 functions funcwithalias
 barexpansion() { print This is the correct output.; }
0:Alias expanded in command substitution does not appear expanded in text
>funcwithalias () {
>	echo $(fooalias)
>This is the correct output.

You'll see that the output from "functions" shown at the end contains
the unexpanded alias (that "0:..." in the middle simply gives the
expected exit status for the code above and a description).  In your
case, that would be the "#", and at the point where it finally does get
read in, in recent shell versions, it's treated like a string, not
interactive input.  If we kept expanded aliases the definition of
functionwithalias would change correspondingly.  Actually, there is an
argument for that since since that's what would happen for an alias in
the main body of the function, but I'm not sure how close the parallels

I'm not sure how much effort this is worth.


Messages sorted by: Reverse Date, Date, Thread, Author