Backticks vs braces in Bash
BashCommand SubstitutionBash Problem Overview
When I went to answer this question, I was going to use the ${}
notation, as I've seen so many times on here that it's preferable to backticks.
However, when I tried
joulesFinal=${echo $joules2 \* $cpu | bc}
I got the message
-bash: ${echo $joules * $cpu | bc}: bad substitution
but
joulesFinal=`echo $joules2 \* $cpu | bc`
works fine. So what other changes do I need to make?
Bash Solutions
Solution 1 - Bash
The ``
is called Command Substitution and is equivalent to $()
(parenthesis), while you are using ${}
(curly braces).
So all of these expressions are equal and mean "interpret the command placed inside":
joulesFinal=`echo $joules2 \* $cpu | bc`
joulesFinal=$(echo $joules2 \* $cpu | bc)
# v v
# ( instead of { v
# ) instead of }
While ${}
expressions are used for variable substitution.
Note, though, that backticks are deprecated, while $()
is POSIX compatible, so you should prefer the latter.
From man bash
:
> Command substitution allows the output of a command to replace the
> command name. There are two forms:
>
> $(command)
> or
> command
Also, ``
are more difficult to handle, you cannot nest them for example. See comments below and also Why is $(...) preferred over ...
(backticks)?.
Solution 2 - Bash
They behave slightly differently in a specific case:
$ echo "`echo \"test\" `"
test
$ echo "$(echo \"test\" )"
"test"
So backticks silently remove the double quotes.
Solution 3 - Bash
${}
refer to Shell parameter expansion. Manual link:https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
> The ‘$’ character introduces parameter expansion, command > substitution, or arithmetic expansion. The parameter name or symbol to > be expanded may be enclosed in braces, which are optional but serve to > protect the variable to be expanded from characters immediately > following it which could be interpreted as part of the name. > > When braces are used, the matching ending brace is the first ‘}’ not > escaped by a backslash or within a quoted string, and not within an > embedded arithmetic expansion, command substitution, or parameter > expansion.
FULLPATH=/usr/share/X11/test.conf_d/sk-synaptics.conf
echo ${FULLPATH##*/}
echo ${FILENAME##*.}
First echo will get filename. second will get file extension as per manual ${parameter##word} section.
$(command)
`command`
refer to command substitution.
> Bash performs the expansion by executing command in a subshell > environment and replacing the command substitution with the standard > output of the command, with any trailing newlines deleted.
https://www.gnu.org/software/bash/manual/html_node/Command-Substitution.html