zsh-users
 help / color / mirror / code / Atom feed
From: Stephane Chazelas <stephane@chazelas.org>
To: Ray Andrews <rayandrews@eastlink.ca>
Cc: zsh-users@zsh.org
Subject: Re: why is eval needed?
Date: Sun, 20 Nov 2022 20:16:59 +0000	[thread overview]
Message-ID: <20221120201659.na4ypuivspeoowhu@chazelas.org> (raw)
In-Reply-To: <c717fdc0-7661-3387-d0c8-3aff56d7f6c7@eastlink.ca>

2022-11-20 08:27:01 -0800, Ray Andrews:
> 
> On 2022-11-20 07:08, Stephane Chazelas wrote:
> > zsh doesn't impose anything. "-L 2" is a string made of 4
> > characters in any shell or programming language. There's no
> > programming language where "-L 2" means 2 strings -L and 2.
> 
> But that's the thing, I'd naively thought the variable could be inserted in
> the command string and be 'just' a string of characters, but zsh imposes
> that 'tree' must see '-L 2' as a single entity, yes?

No, you have it completely backwards. And I think at the heart
of your misunderstanding there is the misconception that you
pass a "command string" to an executable.

You do not, you pass a list of arguments.

On Unix-like systems, execution of commands are with the execve()
system call which takes 3 arguments:

1. the path name to the executable
2. a list of arguments: argv[]
3. a list of environment variables: envp[]

What is commonly refered to as a command line is the shell's
interface to that system call.

VAR1=foo VAR2=bar cmd 'arg 1' arg2

Is how you tell your shell to do a

execve("/path/to/cmd", ["cmd", "arg 1", "arg2"],
[exportedvariable, "VAR1=foo", "VAR2=bar"])


You do not pass the "cmd 'arg 1' arg2" string as argument to
/path/to/cmd.

>  As shown, we need word
> splitting to solve the problem and show tree what it wants to see. Or, as I
> was speculating, some way of just flattening the string back to nothing more
> than a string of characters -- but then again, probably tree wouldn't like
> that either, perhaps the string is always 'packaged' into words?  If so,
> then there's no avoiding that we must word-split '-L 2' into two words and
> there's nothing to wish for.

Why store those two arguments as a string with a space in between them
and then ask the shell to split it, that makes no sense.

Just store those two arguments and pass them to tree, that's exactly
what arrays are for. In several shells like rc or fish, all variables
are arrays (also in csh, but csh has many other issues of its own).
From a design point of view, that's the most sensible thing to do as
what shells deal with primarily is the list of arguments to commands¹

zsh: args=(-L 1); tree $args
rc: args=(-L 1); tree $args
fish: set args -L 1; tree $args
tcsh: set args = (-L 1); tree $args:q
ksh: set -A args -- -L 1; tree "${args[@]}"
ksh93/bash2+(/zsh): args=(-L 1); tree "${args[@]}"

(¹ a complication and a spanner in the works is that environment
variables (those VAR=value strings passed in envp[] above) are
string/scalar only; in csh and in the Bourne shell, shell variables and
env variables were more separated than they are in modern shells).

If you wish

arg='-L 2'
tree $arg

passed "-L" and "2" as separate arguments to tree, do you also wish
that:

file='my file.txt'
rm -- $file

Also passed "my" and "file.txt" as separate arguments to rm for rm to
unlink those 2 files?

What about:

files=(
  'my file.txt'
  'my other file.txt'
)
rm -- $files

Should they be split too?

How about:

text='shutdown|reboot'
echo $text

Should that run echo shutdown|reboot and reboot?


[...]
> > Calls tree with "-L" and "1" as arguments is not that bash
> > doesn't do some sort of magic "grouping" that zsh would be
> > doing, but that ksh/bash contrary to zsh does that extra layer
> > of $IFS-splitting from the Bourne shell on top of the syntax
> > parsing as the default value of $IFS happens to contain the
> > space character.
> Ah!  So my little issue is a zsh exclusive?

No, again, any recent shell (i.e. post 1980) that had no intention of
being compatible with the Bourne shell including rc (and derivatives
like akanga or es) and fish behave like zsh in this instance².

In fish,

set arg '-L 1'
tree $arg

Or in rc/es/akanga:

arg = '-L 1'
tree $arg

all call tree with one "-L 1" argument.

(² and even better, zsh still has that issue that unquoted expansions to
empty removal, one of the issues with Bourne-like shells that it hasn't
fixed. rc/es/akanga/fish have).

>  Not complaining tho, I don't
> like zsh doing things I didn't ask it to do so if in this case I need to
> request a word split that's just fine.  After all it's tree that's being
> difficult so the problem is rare and easily solved.

No, it's not tree being difficult. In any command doing

cmd '-o arg'

is passing the " arg" string as argument to the -o option.

sort '-o file' file

Will sort the "file" file into the " file" file just like you asked. If
you want to sort it into itself, it's sort -o file file

[...]
> > nm is a standard development command (though not -D which AFAIK
> > is a GNU extension). Part of GNU binutils on GNU systems.
> Ah, that's why I can't find it.  It's hard to find commands so packaged.

apt-file is your friend.

For the POSIX standard (2018 edition) see
https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/

[...]
> > Again, tree has nothing to do with the GNU project.
> 
> I dunno, I get it all from Debian and Debian is a GNU/Linux OS so I don't
> know more than that.

On Debian

dpkg -S =tree

Will tell you what package the tree command comes from.

apt showsrc that-package

Will tell you how it was built and generally where the source came from.
Here, not from gnu.org but from http://mama.indstate.edu/users/ice/tree/
http://mama.indstate.edu/users/ice/tree/changes.html shows it has a long
history and might be even as old as zsh.

-- 
Stephane


  reply	other threads:[~2022-11-20 20:17 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-19 14:34 Ray Andrews
2022-11-19 14:43 ` Roman Perepelitsa
2022-11-19 17:02   ` Ray Andrews
2022-11-19 17:10     ` Roman Perepelitsa
2022-11-19 18:02     ` Clinton Bunch
2022-11-19 18:18       ` Roman Perepelitsa
2022-11-19 16:48 ` Stephane Chazelas
2022-11-19 19:12   ` Ray Andrews
2022-11-19 19:50     ` Lawrence Velázquez
2022-11-19 22:21       ` Ray Andrews
2022-11-20  8:55         ` Stephane Chazelas
2022-11-20 13:47           ` Ray Andrews
2022-11-20 15:08             ` Stephane Chazelas
2022-11-20 16:27               ` Ray Andrews
2022-11-20 20:16                 ` Stephane Chazelas [this message]
2022-11-20 22:31                   ` Bart Schaefer
2022-11-21  2:13                     ` Ray Andrews
2022-11-20 22:47                   ` Ray Andrews

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221120201659.na4ypuivspeoowhu@chazelas.org \
    --to=stephane@chazelas.org \
    --cc=rayandrews@eastlink.ca \
    --cc=zsh-users@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).