Understanding Bash Shell Expansion - Command substitution and Arithmetic expansion

Aside from variable expansion, the Bash shell offers several other types of shell expansion features. Of these, command substitution and arithmetic expansion can be useful in Bash shell scripting and are commonly used.

Command substitution

Command substitution replaces the invocation of a command with the output from its execution. This feature allows the output of a command to be used in a new context, such as the argument to another command, the value for a variable and the list for a loop construct.

Command substitution can be invoked with the old form of enclosing the command in back- ticks, such as `[COMMAND]`. However, the preferred method is to use the newer $() syntax, $([COMMAND]).

$ echo "Current time: `date`"
Current time is Thu Jun 5 16:24:24 EDT 2014.
$ echo "Current time: $(date)"
Current time is Thu Jun 5 16:24:30 EDT 2014.

The newer syntax is preferred since it allows for nesting of command substitutions. In the following nested command substitution example, the output of the find command is used as arguments for the tar command, which then has its output stored into the variable TAROUTPUT.

# TAROUTPUT=$(tar cvf /tmp/incremental_backup.tar $(find /etc - type f -mtime -1))
# echo $TAROUTPUT
/etc/group /etc/gshadow /etc/shadow- /etc/passwd /etc/shadow /etc/passwd- /etc/ tuned/active_profile /etc/rht /etc/group- /etc/gshadow- /etc/resolv.conf

Arithmetic expansion

Bash’s arithmetic expansion can be used to perform simple integer arithmetic operations, and uses the syntax $((EXPRESSION)). When enclosed within $(()), arithmetic expressions are evaluated by Bash and then replaced with their results. Bash performs variable expansion and command substitution on the enclosed expression before its evaluation. Like command line substitution, nesting of arithmetic substitutions is allowed.

$ echo $((1+1))
2

$ echo $((2*2))
4

$ COUNT=1; echo $(($(($COUNT+1))*2))
4

Space characters are allowed in the expression used within an arithmetic expansion. The use of space characters can improve readability in complicated expressions or when variables are included.

$ SEC_PER_MIN=60
$ MIN_PER_HR=60
$ HR_PER_DAY=24
$ SEC_PER_DAY=$(( $SEC_PER_MIN * $MIN_PER_HR * $HR_PER_DAY ))
$ echo "There are $SEC_PER_DAY seconds in a day."
There are 86400 seconds in a day.

The following are some of the commonly used operators in arithmetic expressions, along with their meanings.

OPERATOR MEANING
[VARIABLE]++ variable post-increment
[VARIABLE]– variable post-decrement
++[VARIABLE] variable pre-increment
–[VARIABLE] variable pre-decrement
- unary minus
+ unary plus
** exponentiation
* multiplication
/ division
% remainder
+ addition
- subtraction

When multiple operators exist in an expression, Bash will evaluate certain operators in order according to their precedence. For example, multiplication and division operators have higher precedence than addition and subtraction. Single parentheses can be used to group sub-expressions if the evaluation order desired differs from the default precedence.

$ echo $(( 1 + 1 * 2 ))
3
$ echo $(( (1 + 1) * 2 ))
4

The following table lists the order of precedence for commonly used arithmetic operators from highest to lowest. Operators that have equal precedence are listed together.

OPERATOR MEANING
[VARIABLE]++, [VARIABLE]– variable post-increment and post-decrement
++[VARIABLE], –[VARIABLE] variable pre-increment and pre-decrement
-,+ unary minus and plus
** exponentiation
*,/,% multiplication, division, remainder
+,- addition, subtraction