111

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?

mjuarez
  • 16,372
  • 11
  • 56
  • 73
rojomoke
  • 3,765
  • 2
  • 21
  • 30
  • For simple arithmetic, just use Bash's built-in facilities. `joulesFinal=$((joules2 * cpu))` – tripleee Mar 28 '14 at 10:04
  • @tripleee the original question involved non-integer arithmetic, so the built-in wouldn't work – rojomoke Mar 28 '14 at 10:19
  • 1
    Related post: [What is the benefit of using $() instead of backticks in shell scripts?](https://stackoverflow.com/questions/9449778/what-is-the-benefit-of-using-instead-of-backticks-in-shell-scripts). – codeforester Jan 31 '18 at 23:27

3 Answers3

158

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)?.

fedorqui
  • 275,237
  • 103
  • 548
  • 598
  • 4
    I've investigated it, and I have to admit that backtics are indeed compatible with the [POSIX](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_03) standard. However, it is still true that bash deprecated them, and that `$()` is better to handle (+1) – hek2mgl Mar 28 '14 at 10:14
  • 7
    ... also found no "real" deprecation in the [bash project](http://wiki.bash-hackers.org/scripting/obsolete), meaning a hint that backtics will be removed in upcoming versions. Seems using `$()` is just the *preferred way*. sorry for the confusion :) – hek2mgl Mar 28 '14 at 10:22
  • 3
    No problem at all, @hek2mgl , I find it very interesting. I have sometimes read here in SO that it is deprecated, so it is common to think so (I even thought that). But for me, the most important reason to use `$()` instead of ` `` ` is the fact that with the first you can nest, while the second does not allow it. – fedorqui Mar 28 '14 at 10:23
  • now we know :) .. Yeah, the possibility of nesting them with need to escape is a big advantage of `$()`! – hek2mgl Mar 28 '14 at 10:27
  • 7
    Even if you don't nest, backticks are easily overlooked in quite many console fonts. `$()` much less so. – DevSolar Mar 28 '14 at 10:48
  • 3
    You can nest with "\`\`", it's just ugly. "echo \`echo \\`echo abc\\`\`" works. – Daniel Lubarov Mar 10 '16 at 05:47
46

They behave slightly differently in a specific case:

$ echo "`echo \"test\" `"
test

$ echo "$(echo \"test\" )"
"test"

So backticks silently remove the double quotes.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Gunstick
  • 993
  • 10
  • 15
  • Interesting example. I suspect that the contents of $() is run before the outer string has it's special characters handled as opposed to the case in which backquotes are used. If you want to use backquotes and have quotes persist, `echo "\`echo \\"test\\"\`"` will work as the bash slash escape character needs to be escaped for outer string parsing for it to persist for the inner command. – Chad Skeeters Oct 25 '16 at 18:37
  • The difference is due to the difference, how they both handle escaping. This is also different: `"echo \`\$var\`"` and `"echo $($var)"` – FERcsI Nov 12 '22 at 04:47
4

${} 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

jian
  • 4,119
  • 1
  • 17
  • 32