Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the benefit of using $() instead of backticks in shell scripts?

People also ask

What is $() in shell script?

$() – the command substitution. ${} – the parameter substitution/variable expansion.

What is the use of backtick in shell script?

In my Perl scripts, I would use the backtick operator to run a command in the operating system and return the output to continue the logic in the script. The backtick operator is also available in shell scripts, and because it is so easy to combine with other commands, I started using it a lot.

What is the use of dollar hash in shell scripting?

$# is the number of positional parameters passed to the script, shell, or shell function. This is because, while a shell function is running, the positional parameters are temporarily replaced with the arguments to the function. This lets functions accept and use their own positional parameters.

What are Backticks used for Linux?

What you've typed is a backtick - it is the start of an instruction to bash to evaluate what you type as a command. The > is displayed to indicate you are still entering the command on the next line. If you close the backtick you'll find the whole command will run. E.g.


The major one is the ability to nest them, commands within commands, without losing your sanity trying to figure out if some form of escaping will work on the backticks.

An example, though somewhat contrived:

deps=$(find /dir -name $(ls -1tr 201112[0-9][0-9]*.txt | tail -1l) -print)

which will give you a list of all files in the /dir directory tree which have the same name as the earliest dated text file from December 2011 (a).

Another example would be something like getting the name (not the full path) of the parent directory:

pax> cd /home/pax/xyzzy/plugh
pax> parent=$(basename $(dirname $PWD))
pax> echo $parent
xyzzy

(a) Now that specific command may not actually work, I haven't tested the functionality. So, if you vote me down for it, you've lost sight of the intent :-) It's meant just as an illustration as to how you can nest, not as a bug-free production-ready snippet.


Suppose you want to find the lib directory corresponding to where gcc is installed. You have a choice:

libdir=$(dirname $(dirname $(which gcc)))/lib

libdir=`dirname \`dirname \\\`which gcc\\\`\``/lib

The first is easier than the second - use the first.


The backticks (`...`) is the legacy syntax required by only the very oldest of non-POSIX-compatible bourne-shells and $(...) is POSIX and more preferred for several reasons:

  • Backslashes (\) inside backticks are handled in a non-obvious manner:

    $ echo "`echo \\a`" "$(echo \\a)"
    a \a
    $ echo "`echo \\\\a`" "$(echo \\\\a)"
    \a \\a
    # Note that this is true for *single quotes* too!
    $ foo=`echo '\\'`; bar=$(echo '\\'); echo "foo is $foo, bar is $bar" 
    foo is \, bar is \\
    
  • Nested quoting inside $() is far more convenient:

    echo "x is $(sed ... <<<"$y")"
    

    instead of:

    echo "x is `sed ... <<<\"$y\"`"
    

    or writing something like:

    IPs_inna_string=`awk "/\`cat /etc/myname\`/"'{print $1}' /etc/hosts`
    

    because $() uses an entirely new context for quoting

    which is not portable as Bourne and Korn shells would require these backslashes, while Bash and dash don't.

  • Syntax for nesting command substitutions is easier:

    x=$(grep "$(dirname "$path")" file)
    

    than:

    x=`grep "\`dirname \"$path\"\`" file`
    

    because $() enforces an entirely new context for quoting, so each command substitution is protected and can be treated on its own without special concern over quoting and escaping. When using backticks, it gets uglier and uglier after two and above levels.

    Few more examples:

    echo `echo `ls``      # INCORRECT
    echo `echo \`ls\``    # CORRECT
    echo $(echo $(ls))    # CORRECT
    
  • It solves a problem of inconsistent behavior when using backquotes:

    • echo '\$x' outputs \$x
    • echo `echo '\$x'` outputs $x
    • echo $(echo '\$x') outputs \$x
  • Backticks syntax has historical restrictions on the contents of the embedded command and cannot handle some valid scripts that include backquotes, while the newer $() form can process any kind of valid embedded script.

    For example, these otherwise valid embedded scripts do not work in the left column, but do work on the rightIEEE:

    echo `                         echo $(
    cat <<\eof                     cat <<\eof
    a here-doc with `              a here-doc with )
    eof                            eof
    `                              )
    
    
    echo `                         echo $(
    echo abc # a comment with `    echo abc # a comment with )
    `                              )
    
    
    echo `                         echo $(
    echo '`'                       echo ')'
    `                              )
    

Therefore the syntax for $-prefixed command substitution should be the preferred method, because it is visually clear with clean syntax (improves human and machine readability), it is nestable and intuitive, its inner parsing is separate, and it is also more consistent (with all other expansions that are parsed from within double-quotes) where backticks are the only exception and ` character is easily camouflaged when adjacent to " making it even more difficult to read, especially with small or unusual fonts.

Source: Why is $(...) preferred over `...` (backticks)? at BashFAQ

See also:

  • POSIX standard section "2.6.3 Command Substitution"
  • POSIX rationale for including the $() syntax
  • Command Substitution
  • bash-hackers: command substitution

From man bash:

       $(command)
or
       `command`

Bash performs the expansion by executing command and replacing the com-
mand  substitution  with  the  standard output of the command, with any
trailing newlines deleted.  Embedded newlines are not deleted, but they
may  be  removed during word splitting.  The command substitution $(cat
file) can be replaced by the equivalent but faster $(< file).

When the old-style backquote form of substitution  is  used,  backslash
retains  its  literal  meaning except when followed by $, `, or \.  The
first backquote not preceded by a backslash terminates the command sub-
stitution.   When using the $(command) form, all characters between the
parentheses make up the command; none are treated specially.

In addition to the other answers,

$(...)

stands out visually better than

`...`

Backticks look too much like apostrophes; this varies depending on the font you're using.

(And, as I just noticed, backticks are a lot harder to enter in inline code samples.)