You are experiencing the subtleties of the Command Substitution.
The call
doSomething
is a simple function call. It executes the function, pretty much as if you had copy-and-pasted the commands of the function to the place where you call it. Hence, it overwrites the variable number
with the new value 8
.
The call
$(doSomething)
on the other hand is a command substitution. It is meant to execute the function and return whatever the function printed to stdout
. It is usually not used "standalone", but in variable assignments, e.g.,
os_type=$(uname)
That will execute the command uname
, which on a Linux system would print Linux
to the console, and store its result to the shell variable os_type
. Therefore, it doesn't make sense to use a command substitution with a command or function that doesn't output anything, like your doSomething
. Indeed, since the substitution $(doSomething)
is basically a placeholder for the output of doSomething
, the only reason why you don't get a script error there is that your function doesn't output anything. Had you stated, e.g.,
$(uname)
instead of
$(doSomething)
your shell would have tried to execute the command Linux
and generated a
Linux: No such file or directory
error(1).
The key point to understand the effect you observe is that in a command substitution, the command is executed in a subshell, i.e. any changes to variables made are not backpropagated to the shell where you execute the main script. Therefore, while internally it runs the commands of doSomething
and sets a variable number
to 8
, it does so in its own shell process that has nothing to do with the shell process that runs your script (save for the fact that its stdout
is being retrieved), and therefore cannot modify the variable number
you used in the main script.
For further reading, you may want to look at
here on this site, or
for more overview.
(1) On the other hand, this means you can use a command substitution to execute a command whose name you do not know at the time of writing the script, but that you can find out by executing another command you do know.
echo >&2 ...
within the functions called – Manuel Jordan Jun 15 '21 at 15:29stderr
tostdout
. – AdminBee Jun 15 '21 at 15:39echo >&2 ...
- otherwise without>&2
does not work – Manuel Jordan Jun 15 '21 at 16:18