programing

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

elseif 2023. 4. 29. 08:47

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

을 캡처하는 은 두 .bash:

  1. 본 셸 시본셸스백틱레거틱▁legacy백.``:

    var=`command`
    
  2. $()가 아는 되거나, Bourne과 에서는 지원되지 ) (Bash 유고나거하처럼, Bourne 원 POSIX 가닌된않에음는서지지되원셸

    var=$(command)
    

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

가장 중요한 것은 명령어 안에 명령어를 내포할 수 있는 능력입니다. 어떤 형태로든 탈출할 수 있는 방법이 뒷구멍에서 작동하는지 알아내려는 정신을 잃지 않고 말입니다.

어느 정도 고안된 예는 다음과 같습니다.

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

그면당모게파목제것다입니공록할을에 됩니다./dir디렉터리 트리는 2011년 12월의 가장 오래된 날짜 텍스트 파일과 이름이 같습니다.

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

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

(a) 특정 명령이 실제로 작동하지 않을 수 있으므로 기능을 테스트하지 않았습니다.그래서, 만약 당신이 그것에 대해 나를 부결시킨다면, 당신은 의도를 잃어버릴 것입니다 :-) 그것은 단지 당신이 둥지를 틀 수 있는 방법에 대한 예시로서 의미되는 것이지, 버그 없는 생산 준비 스니펫이 아닙니다.

lib 디렉터리가 lib의 위치에 를 합니다.gcc가 설치되어 있습니다.선택할 수 있습니다.

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

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

첫 번째 것이 두 번째 것보다 쉽습니다. 첫 번째 것을 사용하세요.

backticks)`...`)는와 호환되지 않는 오래된 것만 이며, )는 POSIX와 호환되지 않는 bourne-shells입니다$(...)이고 몇 이유로 더 됩니다.

  • \됩니다.

    $ 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와 Dash는 필요하지 않기 때문에 휴대할 수 없습니다.

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

    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
  • 의 내용에 백쿼트를할 수 , 의 백틱스 구문은 백쿼트를 포함합니다.$()양식은 모든 종류의 유효한 포함된 스크립트를 처리할 수 있습니다.

    예를 들어, 유효하지 않은 내장형 스크립트는 왼쪽 열에서는 작동하지 않지만 오른쪽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 ')'
    `                              )
    

따서다대구문한의 은 다음과 같습니다.$- 접두사 명령어 대체는 선호되는 방법이어야 합니다. 깨끗한 구문(인간과 기계의 가독성 향상)으로 시각적으로 명확하고, 중첩 가능하고 직관적이며, 내부 구문 분석이 분리되어 있기 때문입니다.또한 백스틱이 유일한 예외인 경우에도 일관성이 있습니다(이중 패리티 내에서 구문 분석되는 다른 모든 확장과 함께)`캐릭터는 근처에 있을 때 쉽게 위장됩니다."특히 작거나 특이한 글꼴을 사용하면 읽기가 훨씬 더 어려워집니다.

출처: 왜 (배경)보다 선호됩니까?바시에서FAQ

참고 항목:

맨배시에서:

$(명령)또는명령
Bash는 명령을 실행하고 com-을 교체하여 확장을 수행합니다.명령의 표준 출력을 사용한 mand 대체(임의의 경우)후행 새 줄이 삭제되었습니다.포함된 새 줄은 삭제되지 않지만 새 줄은단어 분할 중에 제거될 수 있습니다.명령 대체 $(cat)file)은 동등하지만 더 빠른 $(< file)로 대체할 수 있습니다.

이전 스타일의 백쿼트 형식 대체가 사용되는 경우 백슬래시$, ' 또는 \ 뒤에 오는 경우를 제외하고는 문자 그대로의 의미를 유지합니다.백슬래시가 선행되지 않는 첫 번째 백슬래시는 명령 하위-시설$(명령) 양식을 사용하는 경우 다음 사이의 모든 문자괄호는 명령을 구성합니다. 특별히 처리되는 것은 없습니다.

다른 답변들 외에도,

$(...)

보다 시각적으로 더 눈에 띕니다.

`...`

백스틱은 아포스트로피와 너무 유사합니다. 사용하는 글꼴에 따라 다릅니다.

(그리고 방금 알아차린 것처럼, 백택스는 인라인 코드 샘플에 입력하기가 훨씬 어렵습니다.)

$()중첩을 허용합니다.

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

저는 백트릭은 그것을 허용하지 않는다고 생각합니다.

은 POSIX를 입니다.$(command)명령 대체 형식입니다.오늘날 사용되는 대부분의 셸은 POSIX와 호환되며 구식 백틱 표기법보다 선호되는 형태를 지원합니다.셸 언어 문서의 명령 대체 섹션(2.6.3)에서는 다음과 같이 설명합니다.

명령 대체를 사용하면 명령 이름 대신 명령 출력을 대체할 수 있습니다.명령 대체는 명령이 다음과 같이 동봉될 때 발생합니다.

$(command)

또는 (뒤따옴표로 묶은 버전):

`command`

셸은 하위 셸 환경(셸 실행 환경 참조)에서 명령을 실행하고 명령 대체(명령어 텍스트와 동봉된 "$(")" 또는 백쿼트)를 명령의 표준 출력으로 대체하여 하나 이상의 시퀀스를 제거함으로써 명령 대체를 확장해야 합니다.<newline>대체 끝에 있는 문자입니다. 임드<newline>출력이 끝나기 전의 문자는 제거되지 않아야 합니다. 그러나 IFS의 값과 유효한 인용문에 따라 필드 분할 중에 필드 구분 기호로 처리되고 제거될 수 있습니다.출력에 null 바이트가 포함된 경우 동작은 지정되지 않습니다.

묶은 대체 에서, 뒤서인명대방내에서식체,<backslash>과 같은를 제외하고는 의미를 $' , '`또는<backslash>일치하는 백쿼트에 대한 검색은 첫 번째 인용문이 없는 비도피 백쿼트로 충족되어야 합니다. 이 검색 중 셸 주석, 여기 문서, $(명령) 양식의 포함된 명령 대체 또는 따옴표가 있는 문자열 내에서 비도피 백쿼트가 발생하면 정의되지 않은 결과가 발생합니다." 내에서 시작하지만 끝나지 않는 단일 따옴표 또는 이중 따옴표 문자열`...`시퀀스는 정의되지 않은 결과를 생성합니다.

$(명령) 양식을 사용하면 열린 괄호 뒤에 있는 모든 문자와 일치하는 닫는 괄호가 명령을 구성합니다.지정되지 않은 결과를 생성하는 리디렉션으로만 구성된 스크립트를 제외하고 모든 유효한 셸 스크립트를 명령에 사용할 수 있습니다.

명령 대체 결과는 추가 타일 확장, 파라미터 확장, 명령 대체 또는 산술 확장에 대해 처리되지 않습니다.이중 따옴표 안에서 명령 대체가 발생할 경우 대체 결과에 대해 필드 분할 및 경로 이름 확장을 수행할 수 없습니다.

명령 대체를 중첩할 수 있습니다. 버전에 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " 를 붙여야 .<backslash>문자(예:

\`command\`

은 " 명령어로구문은 " 시는확장대가작 "로 시작하는 모호성을 .$((서브셸로 시작하는 산술 확장 또는 명령 대체를 도입할 수 있습니다.산술 확장이 우선합니다. 즉, 셸은 먼저 확장을 산술 확장으로 구문 분석할 수 있는지 여부를 결정하고 확장을 산술 확장으로 구문 분석할 수 없다고 판단하는 경우에만 명령 대체로 확장을 구문 분석해야 합니다.셸은 이 확인을 수행할 때 중첩 확장을 평가할 필요가 없습니다.확장을 산술 확장으로 구문 분석할 수 없다고 아직 결정하지 않은 상태에서 입력의 끝에 도달하는 경우, 셸은 확장을 불완전한 산술 확장으로 처리하고 구문 오류를 보고해야 합니다.적합한 신청서는 다음을 분리하도록 보장해야 합니다.$(discovery'(하위 셸로 시작하는 명령 대체에서 두 개의 토큰(즉, 공백으로 구분)으로 분할합니다.예를 들어, 단일 하위 셸을 포함하는 명령 대체는 다음과 같이 작성될 수 있습니다.

$( (command) )

는 완벽하게 유효한 예인 ▁of를 .$(...)1파운드가 `...`.

Cygwin을 실행하는 Windows에 원격 데스크톱을 사용하고 있었는데 명령 결과를 반복하려고 했습니다.안타깝게도, 백틱 캐릭터는 원격 데스크톱이나 Cygwin 자체 때문에 입력할 수 없었습니다.

이러한 이상한 설정에서 달러 기호와 괄호를 입력하는 것이 더 쉬울 것이라고 가정하는 것이 현명합니다.

2021년에는 다른 답변에 대한 보충 자료로 이상한 사실을 언급할 가치가 있습니다.

마이크로소프트 데브옵스파이프라인에 대한 YAML "스크립트 작성"에는 Bash 태스크가 포함될 수 있습니다.그러나, 표기법은$()는 YAML 컨텍스트에 정의된 변수를 참조하는 데 사용되므로, 이 경우 명령 출력을 캡처하는 데 백스틱을 사용해야 합니다.

DevOps 프리프로세서는 존재하지 않는 변수에 대해 매우 관대하기 때문에 오류 메시지가 없을 것이기 때문에 스크립트 코드를 YAML 스크립트에 복사할 때 대부분 이 문제가 발생합니다.

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