Programming

쉘 스크립트에서 백틱 대신 $ ()를 사용하면 어떤 이점이 있습니까?

procodes 2020. 6. 16. 22:04
반응형

쉘 스크립트에서 백틱 대신 $ ()를 사용하면 어떤 이점이 있습니까?


명령 행 출력을 캡처하는 두 가지 방법이 있습니다 bash.

  1. 레거시 Bourne 쉘 백틱 ``:

     var=`command`
    
  2. $() 구문 (내가 아는 한 Bash에만 해당되거나 최소한 원래 Bourne과 같은 POSIX가 아닌 오래된 쉘에서는 지원되지 않음)

     var=$(command)
    

백틱과 비교하여 두 번째 구문을 사용하면 어떤 이점이 있습니까? 아니면 두 사람이 완전히 100 % 동일합니까?


주요한 것 중 하나는 명령에 명령 중첩 시킬 수 있다는 것입니다.

예를 들어, 다소 고안되었다.

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

/dir2011 년 12 월 (a) 의 가장 오래된 날짜의 텍스트 파일과 이름이 같은 디렉토리 트리 의 모든 파일 목록이 제공됩니다 .

또 다른 예는 상위 디렉토리의 이름 (전체 경로가 아님)을 얻는 것과 같습니다.

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

(a) 이제 특정 명령이 실제로 작동하지 않을 수 있으므로 기능을 테스트하지 않았습니다. 그래서, 당신이 저에게 투표를한다면, 의도를 잃어버린 것입니다. :-) 그것은 버그가없는 프로덕션 레디 스 니펫이 아니라 어떻게 네 스팅을 할 수 있는지에 대한 예시입니다.


gcc설치된 위치에 해당하는 lib 디렉토리를 찾으려고 가정하십시오 . 선택하실 수 있습니다 :

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

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

첫 번째는 두 번째보다 쉽습니다. 첫 번째를 사용하십시오.


백틱 ( `...`)은 가장 오래된 비 POSIX 호환 bourne-shell에만 필요한 레거시 구문 $(...)이며 POSIX이며 몇 가지 이유로 더 선호됩니다.

  • \백틱 내부의 백 슬래시 ( )는 명확하지 않은 방식으로 처리됩니다.

    $ 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 \\
    
  • 중첩 된 인용문 $()이 훨씬 더 편리합니다.

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

    대신에:

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

    또는 다음과 같은 것을 작성하십시오.

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

    $()인용을 위해 완전히 새로운 맥락을 사용 하기 때문에

    Bourne 및 Korn 쉘에는 이러한 백 슬래시가 필요하지만 Bash 및 대시는 필요하지 않으므로 이식성이 없습니다.

  • 중첩 명령 대체 구문이 더 쉽습니다.

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

    보다:

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

    때문에 $()각 명령의 대체가 보호되고 인용과 이스케이프 이상 특별한 문제없이 자체적으로 처리 할 수 있도록 인용에 대한 완전히 새로운 상황 시행한다. 백틱을 사용하는 경우 레벨이 2 이상이되면 배가 더 나빠집니다.

    몇 가지 더 많은 예 :

    echo `echo `ls``      # INCORRECT
    echo `echo \`ls\``    # CORRECT
    echo $(echo $(ls))    # CORRECT
    
  • 역 따옴표를 사용할 때 일관되지 않은 동작 문제를 해결합니다.

    • echo '\$x' 출력 \$x
    • echo `echo '\$x'` 출력 $x
    • echo $(echo '\$x') 출력 \$x
  • Backticks 구문에는 포함 된 명령의 내용에 대한 기록 제한이 있으며, 역 따옴표를 포함하는 일부 유효한 스크립트를 처리 할 수 ​​없지만 최신 $()양식은 모든 종류의 유효한 포함 된 스크립트를 처리 할 수 ​​있습니다.

    예를 들어, 유효한 다른 내장 스크립트는 왼쪽 열에서 작동하지 않지만 오른쪽 IEEE 에서는 작동합니다 .

    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:


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


$() allows nesting.

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

I think backticks does not allow it.


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


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.

참고URL : https://stackoverflow.com/questions/9449778/what-is-the-benefit-of-using-instead-of-backticks-in-shell-scripts

반응형