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

后端 未结 8 978
梦谈多话
梦谈多话 2020-11-22 05:05

There are two ways to capture the output of command line in bash:

  1. Legacy Bourne shell backticks ``:

    var=`command`
             
    
    
            
相关标签:
8条回答
  • 2020-11-22 05:30

    $() allows nesting.

    out=$(echo today is $(date))
    

    I think backticks does not allow it.

    0 讨论(0)
  • 2020-11-22 05:37

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

    0 讨论(0)
  • 2020-11-22 05:38

    It is the POSIX standard that defines the $(command) form of command substitution. Most shells in use today are POSIX compliant and support this preferred form over the archaic backtick notation. The command substitution section (2.6.3) of the Shell Language document describes this:

    Command substitution allows the output of a command to be substituted in place of the command name itself.  Command substitution shall occur when the command is enclosed as follows:

    $(command)

    or (backquoted version):

    `command`

    The shell shall expand the command substitution by executing command in a subshell environment (see Shell Execution Environment) and replacing the command substitution (the text of command plus the enclosing "$()" or backquotes) with the standard output of the command, removing sequences of one or more <newline> characters at the end of the substitution. Embedded <newline> characters before the end of the output shall not be removed; however, they may be treated as field delimiters and eliminated during field splitting, depending on the value of IFS and quoting that is in effect. If the output contains any null bytes, the behavior is unspecified.

    Within the backquoted style of command substitution, <backslash> shall retain its literal meaning, except when followed by: '$' , '`', or <backslash>. The search for the matching backquote shall be satisfied by the first unquoted non-escaped backquote; during this search, if a non-escaped backquote is encountered within a shell comment, a here-document, an embedded command substitution of the $(command) form, or a quoted string, undefined results occur. A single-quoted or double-quoted string that begins, but does not end, within the "`...`" sequence produces undefined results.

    With the $(command) form, all characters following the open parenthesis to the matching closing parenthesis constitute the command. Any valid shell script can be used for command, except a script consisting solely of redirections which produces unspecified results.

    The results of command substitution shall not be processed for further tilde expansion, parameter expansion, command substitution, or arithmetic expansion. If a command substitution occurs inside double-quotes, field splitting and pathname expansion shall not be performed on the results of the substitution.

    Command substitution can be nested. To specify nesting within the backquoted version, the application shall precede the inner backquotes with <backslash> characters; for example:

    \`command\`

    The syntax of the shell command language has an ambiguity for expansions beginning with "$((", which can introduce an arithmetic expansion or a command substitution that starts with a subshell. Arithmetic expansion has precedence; that is, the shell shall first determine whether it can parse the expansion as an arithmetic expansion and shall only parse the expansion as a command substitution if it determines that it cannot parse the expansion as an arithmetic expansion. The shell need not evaluate nested expansions when performing this determination. If it encounters the end of input without already having determined that it cannot parse the expansion as an arithmetic expansion, the shell shall treat the expansion as an incomplete arithmetic expansion and report a syntax error. A conforming application shall ensure that it separates the "$(" and '(' into two tokens (that is, separate them with white space) in a command substitution that starts with a subshell. For example, a command substitution containing a single subshell could be written as:

    $( (command) )

    0 讨论(0)
  • 2020-11-22 05:43

    This is a legacy question, but I came up with a perfectly valid example of $(...) over `...`.

    I was using a remote desktop to windows running cygwin and wanted to iterate over a result of a command. Sadly, the backtick character was impossible to enter, either due to the remote desktop thing or cygwin itself.

    It's sane to assume that a dollar sign and parentheses will be easier to type in such strange setups.

    0 讨论(0)
  • 2020-11-22 05:47

    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.

    0 讨论(0)
  • 2020-11-22 05:51

    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.

    0 讨论(0)
提交回复
热议问题