Command substitutions
Keith Edmunds
Command substitution enables a command to include the output of another command. For example, we want the symbol THIS_HOST to hold the host name of the system, using the
hostname command. There are two straightforward ways of assigning this to a symbol. The older, deprecated way is to enclose the command in backticks:
$ THIS_HOST=`hostname`
This is still in common use, but it has a number of disadvantages: it’s too easy to misinterpret and nesting substitutions is very challenging.
The preferred modern syntax is to wrap the substituted command in a $(...) construction. Our host name example now becomes:
$ THIS_HOST=$(hostname)
Nesting is now simple. Take assigning the time since a file was last modified, in seconds to the symbol’s age – let’s use FILE to hold the path of the file in question. The last modified time in seconds since the Epoch is like this: $ FILE=/tmp/mytestfile $ touch $FILE $ stat -c %Y ${FILE} 1499673894
Find the current time since the Epoch with:
$ date +%s 1499673946
For the age of the file in seconds:
$ age=$( ( $(date +%s) - $(stat -c %Y ${FILE}) ) ) $ echo $age 52 The two time-since-epoch commands are each wrapped in a $(...) so the above becomes:
$ age=$( (1499673946 - 1499673894) )
Bash does the calculations within a $((...)) and yields the time since the last modification. Yes, it’s confusing: single parentheses for command substitution, and double for expression evaluation. Backticks still work, but I’d suggest it’s worth using the newer form in the future.