help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Running commands as "$@"


From: Cristian Zoicas
Subject: Re: Running commands as "$@"
Date: Thu, 2 Feb 2023 16:29:23 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0 SeaMonkey/2.53.3




Kerin Millar wrote:
On Thu, 2 Feb 2023 12:11:32 +0100
Cristian Zoicas <zoicas@medialab.sissa.it> wrote:

Hello all

Let's assume the following script.

# ---- begin script runner.sh ----
eval "$@"
# ---- end script runner.sh ----


Thank you for your answer. I'll read it as soon as I have some time.

There was a mistake in my original question (I'm very sorry  about that).
I wanted to ask the question not for the script above, but for the following
script (the entire message was relative to this script but by mistake I've
left the eval in the question.)

# ---- begin script runner.sh ----
"$@"
# ---- end script runner.sh ----




If we call this script with the following command line

      $ sh runner.sh ls -l

the 'ls -l' command will be executed.

Now, if a call the script with the commands

      $ sh runner.sh A=B

we get the following errors:

      runner.sh: 10: runner.sh: A=B: not found

That's not what happens in any conforming implementation of sh (see below).

Why the shell does not treat the first string in "$@" ('A=B'
in these cases) as the first possibile token of command (which
is an assignemnt)?

Probably because the script that you presented isn't representative of the 
issue, in so far as you weren't using eval at the time.


In addition, the problem is NOT solved by using 'eval "$@"'.
Apparently it works. For example the command

       $ sh runner.sh A=BCD

   works, but

       $ sh runner.sh A="B    CD"

gives an error. In this case the error (I think) comes
from the way the expansion of "$@" is performed: eval has to evaluate the
string "A=B   CD", so it treats A=B as an assignemnt and 'CD' as
a command.

This is correct.

I think that your questions may be addressed overall by reading 
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_10_02.
 As concerns potential variable assignments that are the leading words of a simple 
command, the parser will only interpret them as such in the case that each of the 
applicable tokens contains an <equals-sign> and is not quoted in any way. Thus, 
the following examples do not work in the way that you might have imagined.

$ set -- A=B
$ "$1"
bash: A=B: command not found
$ 'A=B'
bash: A=B: command not found
$ \A=B
bash: A=B: command not found

Conversely, the following example works because the parameter expansion is 
performed prior to the resulting word(s) being injected into the tokeniser by 
eval. The observed token ends up being A=B, literally.

$ set -- 'A=B'
$ eval "$1"




reply via email to

[Prev in Thread] Current Thread [Next in Thread]