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

Re: Question about expansion: redirection(<) vs command(cat)



Considering that the word here is explicitly a filename to be read, it is quite odd that it doesn't undergo filename generation. If it were not documented, I would even go so far as to suggest that it's a bug. 

Worth noting that both bash and ksh do filename expansion in this construct (triggering an "ambiguous" warning if the pattern expands to more than one filename). Also, zsh's lack of filename expansion here is not affected by GLOB_SUBST.

On Tue, Jan 13, 2026 at 4:19 PM Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
On Tue, Jan 13, 2026 at 11:09 AM Jim <linux.tech.guy@xxxxxxxxx> wrote:
>
> The following produced the expected output.
> Array=(${(f)"$(< /usr/share/zsh/5.9/scripts/newuser)"}) ; print $?
>
> But when expansion is required the following fails.
> Array=(${(f)"$(< /usr/share/zsh/<->.*/scripts/newuser)"}) ; print $?

The issue here is that the token "$(<" is a special case of "$(" and
not a special case of "<" redirection.  Docs under "Command
Substitution":

  The substitution '$(cat FOO)' may be replaced by the faster '$(<FOO)'.
  In this case FOO undergoes single word shell expansions (_parameter
  expansion_, _command substitution_ and _arithmetic expansion_), but not
  filename generation.  No subshell is created.

Note "but not filename generation".



--
Mark J. Reed <markjreed@xxxxxxxxx>


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