There are two syntaxes for command substitution: with dollar-parentheses and with backticks. Running top -p $(pidof init) and top -p `pidof init` gives the same output. Are these two ways of doing the same thing, or are there differences?
- 19See also: BashFAQ/082.Dennis Williamson– Dennis Williamson2011-01-13 16:38:54 +00:00Commented Jan 13, 2011 at 16:38
- 47For a second there I thought this was a jQuery question.David Murdoch– David Murdoch2011-01-13 20:42:03 +00:00Commented Jan 13, 2011 at 20:42
- The result might depend on the shell - some support both.artdanil– artdanil2011-02-15 22:33:39 +00:00Commented Feb 15, 2011 at 22:33
6 Answers
The old-style backquotes ` ` do treat backslashes and nesting a bit different. The new-style $() interprets everything in between ( ) as a command.
echo $(uname | $(echo cat)) Linux echo `uname | `echo cat`` bash: command substitution: line 2: syntax error: unexpected end of file echo cat works if the nested backquotes are escaped:
echo `uname | \`echo cat\`` Linux backslash fun:
echo $(echo '\\') \\ echo `echo '\\'` \ The new-style $() applies to all POSIX-conformant shells.
As mouviciel pointed out, old-style ` ` might be necessary for older shells.
Apart from the technical point of view, the old-style ` ` has also a visual disadvantage:
- Hard to notice:
I like $(program) better than `program` - Easily confused with a single quote:
'`'`''`''`'`''`' - Not so easy to type (maybe not even on the standard layout of the keyboard)
(and SE uses ` ` for own purpose, it was a pain writing this answer :)
- 12The only thing I would add, is that I call '(' a paren, not a bracket (which is '[').Kendall Helmstetter Gelner– Kendall Helmstetter Gelner2011-01-13 18:09:57 +00:00Commented Jan 13, 2011 at 18:09
- @Kendall: and here I thought '{' was the left bracket for all those years...SamB– SamB2011-01-13 20:32:13 +00:00Commented Jan 13, 2011 at 20:32
- 7@Sam:
{ }is usually called "curly brackets" or "braces" en.wikipedia.org/wiki/Braces_(punctuation)#BracesJørn Schou-Rode– Jørn Schou-Rode2011-01-13 21:35:41 +00:00Commented Jan 13, 2011 at 21:35 - 2I also refer to '{' as curly braces. Though it seems odd you need to add the qualifier "curly" if you call the other things brackets... I guess it's just because they actually curl.Kendall Helmstetter Gelner– Kendall Helmstetter Gelner2011-01-14 04:23:53 +00:00Commented Jan 14, 2011 at 4:23
- 1@slim I don't know on US/UK keyboards, but on spanish keyboards
`is a dead key, so I have to type either a double-backtick (something I usually forget I can even do) or backtick then space, which is a pain.Dani– Dani2014-04-04 16:39:25 +00:00Commented Apr 4, 2014 at 16:39
Obvious difference I observe is that you cannot nest backticks while you can nest $(). Maybe both exist for legacy reasons. Similarly, the . and source commands are synonyms.
- 10Some Bourne-derived shells don't recognize
source. Dash is one example.Dennis Williamson– Dennis Williamson2011-01-13 16:40:37 +00:00Commented Jan 13, 2011 at 16:40 - 15That's not true. You can nest backtick to any level, just more painfully. Note that both
$(...)and`...`are standard (the latter being deprecated) while.is standard but notsourceStéphane Chazelas– Stéphane Chazelas2012-10-25 10:17:03 +00:00Commented Oct 25, 2012 at 10:17 - 3Correction, only in
(t)cshcan they not be nested.(t)cshdon't support$(...)though. They do supportsource(and not.) though.Stéphane Chazelas– Stéphane Chazelas2014-08-01 12:28:52 +00:00Commented Aug 1, 2014 at 12:28 - 1"you cannot nest backticks" is only accurate if we imply "without any other addition or modification, i.e. without adding any escape characters". But I guess (also based on the downvotes and on the previous, upvoted comments) this is not how most people read it. A clarifying "without adding proper escaping at each nesting level" would significantly improve this answer's clarity.fra-san– fra-san2020-10-01 11:59:07 +00:00Commented Oct 1, 2020 at 11:59
$() does not work with old Bourne shell. But it has been years decades since I worked with old Bourne shell.
- Old as in 1970's and early 1980's, correct?Christopher– Christopher2019-10-01 19:15:16 +00:00Commented Oct 1, 2019 at 19:15
To add to what others said here, you can use the backticks to simulate inline comments:
echo foo `# I'm a comment!` bar The output is: foo bar.
See the following for more information: https://stackoverflow.com/a/12797512 (Note also the comments below that post.)
Another note, $() will use more system resource than using backticks, but is slightly faster.
In Mastering Unix shell scripting, Randal K. Michael had done a test in a chapter named "24 Ways to Process a File Line-by-Line".
- 2This claim is nonsense. There is no reason why it should be faster as it is just using a different notation for the parser.schily– schily2015-09-06 13:17:04 +00:00Commented Sep 6, 2015 at 13:17
- @schily: Maybe, I only quote from the book, you can read it for more details.cuonglm– cuonglm2015-09-06 15:19:40 +00:00Commented Sep 6, 2015 at 15:19
- 3I would tend to agree with @schily...why would it take more resources?Wildcard– Wildcard2016-03-07 23:21:22 +00:00Commented Mar 7, 2016 at 23:21
- 2@Wildcard, I suppose it's because
$()makes your script one byte bigger than if it used`(assuming you don't nest them and don't use backslashes within). As to which would be faster to parse, that would vary between shells and would be irrelevant as negligible compared to the cost of creating a pipe and forking of process which command substitution entails.Stéphane Chazelas– Stéphane Chazelas2016-12-02 09:45:02 +00:00Commented Dec 2, 2016 at 9:45
The $() syntax will not work with the old bourne shell.
With newer shells ` ` and $() are equivalent but $() is much more convenient to use when you need to nest multiple commands.
For instance :
echo $(basename $(dirname $(dirname /var/adm/sw/save ))) is easier to type and debug than :
echo `basename \`dirname \\\`dirname /var/adm/sw/save \\\`\`` - 1While $() may look nice, it is a pain when implementing a related parser because it requires a dual recursive parser.schily– schily2015-09-06 13:18:23 +00:00Commented Sep 6, 2015 at 13:18
- 8@schily On the other side, what would be a shell without a good parser.Emmanuel– Emmanuel2015-09-08 15:58:29 +00:00Commented Sep 8, 2015 at 15:58
- 1The problem is that you need to know where the string ends before you call the parser. This is relatively simple with the backticks, but it is hard with brackets as they are used for various purposes in the shell. So you need the parser twice and in a way that does not exist in the Bourne Shell.schily– schily2015-09-08 20:04:15 +00:00Commented Sep 8, 2015 at 20:04