help-bash
[Top][All Lists]
Advanced

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

Re: Shell Expansion


From: Greg Wooledge
Subject: Re: Shell Expansion
Date: Wed, 14 Apr 2021 09:15:17 -0400

On Wed, Apr 14, 2021 at 10:58:58AM +0200, robivad wrote:
> Considering the following:
> $(((5+2)))
> 7: command not found

Best thing to do: don't write code like that.  Why make your life harder
by writing things that will have unpredictable behavior?

> 1) I think that the shell first recognizes the command substitution and
> then the arithmetic substitution.
> 2) shell executes first the arithmetic substitution and then the command
> substitution
> 
> Is the order of parsing different from the order of execution or is the
> order on the image wrong? Why $((((5+2)))) gives 7: command not found just
> like $(((5+2))) ?

The shell's parser has to figure out how to interpret this.  The thing
you've written is ambiguous, so we can't say what *should* happen, only
what *does* happen, and even then, we don't know that this is what
will *always* happen in the future.

The choice the parser must make is whether the outermost layer is a
command substitution, or an arithmetic substitution.  In other words,
which one of the two following unambiguous constructs does the parser
choose:

$( ((5+2)) )
$(( (5+2) ))

Based on the error message you're getting, it's clear that it chose the
second.  We can confirm this if we simply run them both and compare the
results:

unicorn:~$ $( ((5+2)) )
unicorn:~$ $(( (5+2) ))
bash: 7: command not found

In the first one, the outermost layer is a command substitution, so first
we run the inner command, and then we take its standard output, and run
that as a second command.  The standard output of ((5+2)) is the empty
string, so we run the empty string as a command, and voila -- nothing
happens.

In the second one, the outermost layer is an arithmetic substitution,
so we evaluate the expression inside as an arithmetic expression, take
its final form as the result. and then replace the arithmetic substitution
with that result.  Since the arithmetic substitution is the first word of
the command you typed, that means we try to run the result as a command.
Thus, "bash: 7: command not found".

As for why bash chooses one over the other -- who knows?  In fact,
I remember that there was a whole Big Thing around this in the early
bash 2.0 days, when $(( )) was introduced (replacing the deprecated
$[ ] syntax).  People who had written scripts that nested an explicit
subshell inside a command substitution without putting spaces between
the parentheses ran into breakage.

So, once again, my best suggestion to you is that you put some whitespace
between the syntax elements you're using, rather than smashing them all
together and letting the shell guess what you meant.



reply via email to

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