291
votes

To store the output of a command as a variable in sh/ksh/bash, you can do either

var=$(command)

or

var=`command`

What's the difference if any between the two methods?

6
Please see BashFAQ/082.Dennis Williamson
You will find the nested issue detailed in the Git Coding Guideline: see my answer below.VonC

6 Answers

299
votes

The backticks/gravemarks have been deprecated in favor of $() for command substitution because $() can easily nest within itself as in $(echo foo$(echo bar)). There are other differences such as how backslashes are parsed in the backtick/gravemark version, etc.

See BashFAQ/082 for several reasons to always prefer the $(...) syntax.

Also see the POSIX spec for detailed information on the various differences.

40
votes

They behave the same. The difference is syntactical: it's easier to nest $() than ``:

listing=$(ls -l $(cat filenames.txt))

vs.

listing=`ls -l \`cat filenames.txt\``
29
votes

July 2014: The commit f25f5e6 (by Elia Pinto (devzero2000), April 2014, Git 2.0) adds to the nesting issue:

The backquoted form is the traditional method for command substitution, and is supported by POSIX.
However, all but the simplest uses become complicated quickly.
In particular, embedded command substitutions and/or the use of double quotes require careful escaping with the backslash character
.

That is why the git/Documentation/CodingGuidelines mentions:

We prefer $( ... ) for command substitution; unlike ``, it properly nests.
It should have been the way Bourne spelled it from day one, but unfortunately isn't.

thiton commented:

That is why `echo `foo`` won't work in general because of the inherent ambiguity because each ``can be opening or closing.
It might work for special cases due to luck or special features.


Update January 2016: Git 2.8 (March 2016) gets rid of backticks entirely.

See commit ec1b763, commit 9c10377, commit c7b793a, commit 80a6b3f, commit 9375dcf, commit e74ef60, commit 27fe43e, commit 2525c51, commit becd67f, commit a5c98ac, commit 8c311f9, commit 57da049, commit 1d9e86f, commit 78ba28d, commit efa639f, commit 1be2fa0, commit 38e9476, commit 8823d2f, commit 32858a0, commit cd914d8 (12 Jan 2016) by Elia Pinto (devzero2000).
(Merged by Junio C Hamano -- gitster -- in commit e572fef, 22 Jan 2016)

From Git 2.8 onwards, it is all $(...), no more `...`.

27
votes

When the older back-tick form is used, backslash retains its literal meaning except when followed by $, `, or \. The first back-tick not preceded by a backslash terminates the command substitution.

When using the newer $(command) form, all characters between the parentheses make up the command; none are treated specially.

Both forms can be nested, but the back-tick variety requires the following form.

`echo \`foo\`` 

As opposed to:

$(echo $(foo))
6
votes

There is little difference, except for what unescaped characters you can use inside of the command. You can even put `...` commands inside $(...) ones (and vice versa) for a more complicated two-level-deep command substitution.

There is a slightly different interpretation of the backslash character/operator. Among other things, when nesting `...` substitution commands, you must escape the inner ` characters with \, whereas with $() substition it understands the nesting automatically.

0
votes

"What's the difference if any between the two methods?"

Make attention to this behaviour:

A="A_VARIABLE"
echo "$(echo "\$A")"
echo "`echo "\$A"`"

You will get these results:

$A
A_VARIABLE