Backticks vs braces in Bash

BashCommand Substitution

Bash 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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionrojomokeView Question on Stackoverflow
Solution 1 - BashfedorquiView Answer on Stackoverflow
Solution 2 - BashGunstickView Answer on Stackoverflow
Solution 3 - BashMarkView Answer on Stackoverflow