If eval does execute the resulting command before expansion of $() takes place—which I expect—the result should be an error for hello world is not executable (unless there is an actual hello command)
That is not how substitution works. The mere presence of $(..)
is what causes the eval
to even run
To start with, $(..)
Command substitution in bash is a way to capture the output of command run inside parens and storing it in a variable. The $(..)
is replaced by output of contents present inside it
The part a=$(eval echo hello world)
is executed by the shell in following order. The eval echo hello world
is executed simply as echo hello world
which runs the echo command and outputs the string hello world
which is stored into the variable a
.
The part $(eval echo hello world)
just returns hello world
as explained in 1). But there is no assignment to capture the output of $(..)
anywhere. So a literal string is returned back to the shell i.e. hello world
. The shell tries to interpret that as a command (the literal hello
string). Hence the error you see, that a command not found of the name
The same happens for a=$(hello world)
also. As mentioned in 1), the part $(..)
runs the contents inside the parens as commands. So the literal string is evaluated again resulting in the same error.
In cases 2) and 3), when the $(..)
is expanded, the literal unquoted string hello world
was returned back to the shell which was subject to word splitting causing hello
and world
as two separate words. Thats why you encounter the error that hello
was run as a command and not the whole string hello world
.
Be cautious in using eval
with any command, as simple as even echo
. There is a risk of executing dangerous commands when not properly invoked. See Is it always safe to use eval echo
?
eval echo hello world
expands tohello world
so basically I expected after expansion it would be equal to the last linea=$(hello world)
. – karlsebal Sep 17 '21 at 18:35$(..)
is replaced by the output of the commands ran inside. So the$(..)
is no longer present onceeval echo
is ran – Inian Sep 17 '21 at 18:41