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

Re: Counting characters in command output?



Entering this conversation here because it seems to be the point after
which it sort of went off the rails.  Go away for a few days and look
what I get ...

On Tue, Feb 13, 2024 at 10:49 PM Roman Perepelitsa
<roman.perepelitsa@xxxxxxxxx> wrote:
>
> On Wed, Feb 14, 2024 at 1:46 AM Mark J. Reed <markjreed@xxxxxxxxx> wrote:
> >
> > On Tue, Feb 13, 2024 at 3:41 PM Roman Perepelitsa <roman.perepelitsa@xxxxxxxxx> wrote:
> >>
> >> Process substitution gives you an array. Quote it if you need a scalar.
> >
> > You mean command substitution, but thanks! It wouldn't have
> > occurred to me to put quotes around it to change what the `#` was
> > counting!
>
> Right, command substitution. In my opinion, it's unfortunate that
> command substitution in zsh splits on IFS by default. I wish this
> wasn't the case.

This is a case where original author Paul Falstad chose to stick to
the behavior common to other shells.  In particular ...

In all extent shells at the time, but especially in BSD csh, `command`
(backticks) splits its output into words.
$(command) and `command` are supposed to be equivalent (except for nesting).
Therefore $(command) splits its output into words, as happens in every
other shell.

The only place zsh introduced a distinction from the default splitting
behavior of other shells was in parameter expansion.

> It's not even common that one wants to split command
> output into words.

The presumption is that most uses of `command` and $(command) are in
the argument list of other commands (for example, that every word of
the output is a file name), and that anyone coming to zsh from another
shell (which again at the time was the vast majority of zsh users)
would be confused if that behavior were not preserved for backticks
and therefore also for $(...).

If you're using it in an assignment and not to create an argument
list, it's entirely consistent with the behavior of scalars and arrays
that
   scalar=`command`
suppresses splitting (unless the appropriate option is set!) whereas
   array=(`command`)
does not, and if you don't want the splitting behavior then you have
quoting (or prior assignment) to make your intention clear.

If you want command substitution without word splitting, then in
whatever the next version ends up being called you have
   ${ command }
to do that for you, and I am very sorry that I wasn't around two days
ago to say that.

Just for evidence sake:

$ csh
% ls `echo a b c`
ls: cannot access 'a': No such file or directory
ls: cannot access 'b': No such file or directory
ls: cannot access 'c': No such file or directory




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