Command substitution is used to insert the output of one command into a second command.
E.g. with an assignment:
today=$(date) # Starts the "date" command, captures its output. echo "$today"
returns:
Mon Jul 26 13:16:02 MEST 2004
This can also be used with other commands besides assignments:
echo "Today is $(date +%A), it's $(date +%H:%M)"
returns:
Today is Monday, it's 13:21
NOTE: This calls the date command two times.
Of course, this could just be done with:
date "+Today is %A, it's %H:%M"
NOTE: As with all substitutions, the results of a command substitution will undergo WordSplitting, unless the whole thing is inside double quotes.
Command substitutions may be nested within each other:
IPs=($(awk /"$(</etc/myname)"/'{print $1}' /etc/hosts))
Notably, once inside a command substitution, the shell begins an entirely new quoting context.
That is, double quotes inside the substitution do not match up with double quotes outside the substitution.
So, things like this may be done:
echo "The IPs are $(awk /"$(</etc/myname)"/'{print $1}' /etc/hosts | tr '\n' ' ')"
NOTE:
Command substitutions create subshells, so any changes to variables, current directory, etc. inside the command substitution affect only the rest of the substitution, and not the parent shell.
var=$(cd ../../usr/bin; pwd) echo "$var"
returns:
/usr/bin
But now run:
pwd
returns:
/home/peter
NOTE: The exit status of the last command that was executed in the subshell is used as the exit status for the command substitution.
var=$("non existent command") bash: non existent command: command not found echo $? 127
NOTE: Command substitutions strip all trailing newlines from the output of the command inside them.
This allows common cases such as foo=$(grep foo bar) to populate variables without needing a second step to remove the newline.
Sometimes, you may want the newlines; for example, when attempting to read an entire file into a variable without data loss (except NUL bytes):
var=$(<file) # strips trailing newlines # Workaround: var=$(cat file; printf x) var=${var%x}
The $(command) syntax is supported by KornShell, BASH, and PosixShell.
Older shells (e.g. BourneShell) use the following syntax:
`command`
NOTE: These are not the apostrophe characters '…', but small ticks going from the upper left to the lower right: `…`.
These are often called “backticks” or “back quotes”.
The use of $(<file) instead of $(cat file) is a Bashism that is slightly more efficient (doesn't require forking a cat(1) process) but obviously less portable.
Nesting of command substitutions using the `…` syntax is more difficult.
One must use backslashes:
IPs_inna_string=`awk "/\`cat /etc/myname\`/"'{print $1}' /etc/hosts` # Very Bourne-ish: use the positional params as a pseudo array set -- `awk "/\`cat /etc/myname\`/"'{print $1}' /etc/hosts`
NOTE: As one may imagine, this becomes rather unwieldy after two levels.