I was wondering: When I e.g. call
list=$(ps -ax)
is ps -ax executed once and I can read the value multiple times or is the command executed every time I call $list
I was wondering: When I e.g. call
list=$(ps -ax)
is ps -ax executed once and I can read the value multiple times or is the command executed every time I call $list
Solution is, that the result is stored. To test that, I used the following script
#!/bin/sh
myTime=$(date)
for a in 1 2 3 4
do
echo 'Stored command: '$myTime
echo 'Fresh command: '$(date)
sleep 2
done
Result looks like this:
Stored commandTue Sep 29 17:39:44 +02 2020
Fresh commandTue Sep 29 17:39:44 +02 2020
Stored commandTue Sep 29 17:39:44 +02 2020
Fresh commandTue Sep 29 17:39:46 +02 2020
Stored commandTue Sep 29 17:39:44 +02 2020
Fresh commandTue Sep 29 17:39:48 +02 2020
Stored commandTue Sep 29 17:39:44 +02 2020
Fresh commandTue Sep 29 17:39:50 +02 2020
Feel free to add missing tags; not sure about how to make stuff like $() most search engine friendly
POSIX sh guarantees that the command will not be re-executed, see below.
Be careful about concluding things about POSIX sh through empirical tests. For example, if you time sleep 60 | true
, you'd find that bash, ksh, zsh and dash all take 60 seconds. However, POSIX sh still allows it to finish immediately.
The shell shall expand the command substitution by executing command in a subshell environment (see Shell Execution Environment) and replacing the command substitution (the text of command plus the enclosing "$()" or backquotes) with the standard output of the command.
and when it's applied:
When a given simple command is required to be executed [...] the following expansions, assignments, and redirections shall all be performed from the beginning of the command text to the end:
[...]
- Each variable assignment shall be expanded for tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal prior to assigning the value.
[...]
Variable assignments shall be performed as follows:
If no command name results, variable assignments shall affect the current execution environment.
Since $()
is replaced with the text of the command, and this happens before the variable is assigned, the command is guaranteed not to be re-executed in a conforming POSIX sh implementation.
To cite the bash manpage:
Command Substitution
Command substitution allows the output of a com-
mand to replace the command name. There are two forms:
$(command)
or
`command`
So the output of the command is stored, not the command itself.
If you want to store a command that is evaluated each time, you need to use eval
:
#!/bin/bash
command="date"
startTime=$(date)
for i in `seq 1 4`
do
echo "$i: $startTime - " $(eval $command)
sleep 1
done