Backticks vs braces in Bash

44,523

Solution 1

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

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

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

Share:
44,523
rojomoke
Author by

rojomoke

Updated on December 19, 2021

Comments

  • rojomoke
    rojomoke over 2 years

    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?

  • hek2mgl
    hek2mgl over 10 years
    I've investigated it, and I have to admit that backtics are indeed compatible with the POSIX standard. However, it is still true that bash deprecated them, and that $() is better to handle (+1)
  • hek2mgl
    hek2mgl over 10 years
    ... also found no "real" deprecation in the bash project, meaning a hint that backtics will be removed in upcoming versions. Seems using $() is just the preferred way. sorry for the confusion :)
  • fedorqui
    fedorqui over 10 years
    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.
  • hek2mgl
    hek2mgl over 10 years
    now we know :) .. Yeah, the possibility of nesting them with need to escape is a big advantage of $()!
  • DevSolar
    DevSolar over 10 years
    Even if you don't nest, backticks are easily overlooked in quite many console fonts. $() much less so.
  • Daniel Lubarov
    Daniel Lubarov over 8 years
    You can nest with "``", it's just ugly. "echo `echo \`echo abc\``" works.
  • Chad Skeeters
    Chad Skeeters over 7 years
    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.