*sh 쉘에서는 백틱(예: "cmd")이 더 이상 사용되지 않습니까?

*sh 쉘에서는 백틱(예: "cmd")이 더 이상 사용되지 않습니까?

나는 Unix, Linux 및 Bash 및 Zsh와 같은 셸과 관련하여 "백틱은 더 이상 사용되지 않습니다"라는 문구를 사용하는 기타 사이트에서 이 주석을 여러 번 보았습니다.

이 진술은 사실인가, 거짓인가?

답변1

"사용되지 않음"에는 두 가지 다른 의미가 있습니다.

더 이상 사용되지 않음:(주로 소프트웨어 기능)을 사용할 수 있지만 더 이상 사용되지 않는 것으로 간주되므로 일반적으로 대체되었기 때문에 피하는 것이 가장 좋습니다.

——새로운 옥스퍼드 미국 사전

이 정의에 따르면 백틱더 이상 사용되지 않습니다.

더 이상 사용되지 않는 상태또한 가능이 기능은 향후 제거될 것임을 나타냅니다.

위키피디아

이 정의에 따르면 백틱은아니요더 이상 사용되지 않습니다.

계속 지원됨:

Open Group Shell 명령 언어 사양, 특히 섹션에 대한 참조2.6.3 명령 대체, 사양의 범위 내에서 백틱( `..cmd..`) 또는 달러 괄호( )의 두 가지 형태의 명령 대체가 여전히 지원된다는 것을 알 수 있습니다.$(..cmd..)

명령 대체를 사용하면 명령 이름 자체를 명령의 출력으로 바꿀 수 있습니다. 명령 대체는 명령에 다음이 포함된 경우 발생합니다.

$(command)
          

또는 (백틱 버전):

`command`

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

백틱 스타일의 명령 대체에서는<백슬래시>`"$", " " 또는 "" 가 뒤에 오지 않는 한 문자 그대로의 의미를 유지해야 합니다.<백슬래시>. 일치하는 역따옴표 검색은 이 검색 중에 인용되지 않고 이스케이프 처리되지 않은 첫 번째 역따옴표로 충족됩니다. 이스케이프 $(command)처리되지 않은 역따옴표에 대해 정의되지 않은 결과가 발생합니다. " " 시퀀스로 시작하지만 끝나지 않는 작은따옴표 또는 큰따옴표 문자열은 `...`정의되지 않은 결과를 생성합니다.

$(command)형식의 경우 왼쪽 대괄호 다음부터 일치하는 오른쪽 대괄호까지 포함하는 모든 문자가 명령을 구성합니다. 지정되지 않은 결과를 생성하는 리디렉션만 포함하는 스크립트를 제외하고 모든 유효한 셸 스크립트를 명령과 함께 사용할 수 있습니다.

그렇다면 왜 모두가 백틱이 더 이상 사용되지 않는다고 말하는 걸까요?

대부분의 사용 사례 때문에~해야 한다백틱 대신 달러 괄호 형식을 사용하세요. (위의 첫 번째 의미에서는 더 이상 사용되지 않습니다.) 가장 평판이 좋은 많은 사이트(U&L 포함)에서도 이 내용을 자주 언급하므로 이는 건전한 조언입니다. 이 권장 사항을 셸에서 백틱 지원을 제거하려는 존재하지 않는 계획과 혼동해서는 안 됩니다.

노트:세 번째 발췌(위)에서는 백틱이 전혀 작동하지 않지만 다음 단락부터 시작하여 최신 달러 대괄호 접근 방식이 작동하는 여러 상황을 보여줍니다.

또한 백틱 구문에는 포함된 명령의 내용에 대한 역사적 제한이 있습니다. 최신 "$()" 양식은 모든 유형의 유효한 내장 스크립트를 처리할 수 있지만, 백틱 양식은 백틱을 포함하는 일부 유효한 스크립트를 처리할 수 없습니다.

해당 섹션을 계속 읽으면 실패가 강조 표시되어 어떻게 백틱 사용이 실패했는지 보여주지만 최신 달러 대괄호 표기법을 사용하면 작동합니다.

결론적으로

따라서 백틱 대신 달러 괄호를 사용하는 것이 더 좋지만 실제로는 "이것은 어떤 계획 시점에서 완전히 작동하지 않을 것입니다"와 같이 기술적으로 "더 이상 사용되지 않는" 항목을 사용하지 않습니다.

이 모든 내용을 읽은 후에는 달러 괄호를 사용하는 것이 매우 권장된다는 점을 이해해야 합니다.구체적으로POSIX가 아닌 실제 Bourne 쉘과의 호환성이 필요합니다.

답변2

더 이상 사용되지는 않지만 역따옴표( `...`)는 가장 오래된 비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`
    

    완전히 새로운 인용 컨텍스트가 적용 되므로 $()각 명령 대체가 보호되며 인용 및 이스케이프에 특별한 주의를 기울이지 않고도 개별적으로 처리할 수 있습니다. 백틱을 사용하면 두 수준 이상부터는 점점 더 보기 흉해집니다.

    다음은 몇 가지 추가 예입니다.

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

$따라서 -prefixed 구문은명령 대체시각적으로 명확하고 구문이 명확하며(사람과 기계의 가독성 향상) 중첩 가능하고 직관적이며 내부 구문 분석이 독립적이며 일관성도 더 높기 때문에 선호되는 접근 방식입니다(다른 모든 확장은 내부에서 구문 분석됨). )(백틱이 유일한 예외임), `문자가 인접한 경우 쉽게 위장될 수 있어 "특히 작거나 특이한 글꼴의 경우 읽기가 더 어려워집니다.

원천:왜 (백틱) $(...)보다 우선합니까 ?`...`배쉬 FAQ

또한보십시오:

답변3

귀하의 제목이 약간 오해의 소지가 있고 귀하의 질문과 다르다는 점에 유의하십시오.반품제목의 질문에 답하십시오(그리고 sh/bash 변형에 관한 정답에 동의하지 마십시오).

귀하의 질문 텍스트는 특히 bash/zsh를 참조하지만 제목은 *에 대해 묻습니다.껍데기. 말하다*껍데기더 넓게문제를 해결하고 여전히 많이 사용되는 csh 및 tcsh와 같은 셸을 정식으로 포함합니다.

예, 많은 사람들이 tcsh를 싫어하고 종종 tcsh를 다음과 같이 사용하면 안 되는 온갖 종류의 이유를 제시한다는 것을 알고 있습니다.스크립팅 언어(동의합니다) 단순히 대화형 쉘로 사용할 가능성을 무시하십시오. (솔직히 왜 *sh를 프로그래밍 언어로 사용하는지 잘 모르겠습니다... 하지만 계속 진행하겠습니다).

csh/tcsh에서 백틱은 다음과 같아야 합니다.아니요부분적으로는 더 이상 사용되지 않습니다.아니요$()가 지원됩니다.

따라서 우리는 백틱이 더 이상 사용되지 않기 때문에 bash 변형이 백틱을 "더 이상 사용하지 않는다"는 것을 알고 있습니다.아니요어떤 의미에서는 곧(혹은 영원히) 삭제될 것입니다. 우리는 csh/tcsh가 백틱을 지원한다는 것도 알고 있습니다.

글쎄요, stackexchange와 같은 사이트에서 질문에 답할 때 $() 솔루션을 선호하는 복잡한 인용을 포함하지 않는 간단한 예에 실제로 백틱을 사용해야 한다는 괜찮은 주장을 할 수 있습니다. 이렇게 하면 bash 사용자를 위해 직접 답변을 해결하고 다른 쉘을 사용하고 $() bourne 구문을 알지 못하는 덜 고급 사용자를 혼란스럽게 하는 대신 답변의 이식성이 더 높아집니다.

참고 사항 및 또 다른 FAQ로 대신 환경 변수를 명령으로 내보내는 예를 제공하는 것이 더 편리할 것입니다.

% VAR=value some_command arg1 arg2 ...

이는 sh/bash 변형에서만 작동하며 다음과 같이 간단히 수행할 수 있습니다.

% env VAR=value some_command arg1 arg2 ...

기적적으로 귀하의 답변은 이제 대부분의 쉘에서 작동합니다.

Stackexchange와 같은 사이트의 글로벌 답변은 일반적으로 어떤 쉘을 사용해야 하는지에 대한 입장을 취하기보다는 가능한 한 혼란을 최소화하면서 최대한 많은 사용자를 위한 문제를 해결하는 것이어야 합니다.

나는 이것이 귀하의 원래 (분명히 오래된) 질문과 다소 관련이 있다는 것을 알고 있지만 문제는 이 질문에 대한 답변이 사람들이 $() 스택 교환 답변에 사용해야 한다고 제안하는 것으로 인용되었으므로 각주를 언급할 가치가 있을 것입니다.

관련 정보