명령 대체를 통해 할당에 큰따옴표 중첩

명령 대체를 통해 할당에 큰따옴표 중첩

스택 오버플로답변3.5K 이상의 표를 얻은 누군가는 이 한 줄을 사용하여 DIR현재 bash 스크립트의 디렉터리를 할당했습니다.

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

중첩된 큰따옴표가 혼란스럽습니다. 내가 아는 한, 다음 스니펫은 큰따옴표로 묶여 있습니다.

"$( cd "
"${BASH_SOURCE[0]}"
" && pwd )"

=... (즉 and) $( dirname오른쪽에 있는 다른 모든 항목은 )인용되지 않습니다. 즉, 두 번째, 네 번째, 여섯 번째 "문자가 각각 첫 번째, 세 번째, 다섯 번째 "문자를 "닫는" 것으로 가정합니다.

큰따옴표가 무엇인지 이해합니다 "${BASH_SOURCE[0]}". 그런데 다른 두 쌍의 큰따옴표의 목적은 무엇입니까?

반면에, 높은 투표에도 불구하고 위의 코드 조각이 잘못된 경우 명목상의 의도를 달성하는 올바른 방법은 무엇입니까?

(통과명목상의 의도pwd내 말은: 첫 번째 -ing에 의해 반환된 값을 cd반환된 디렉터리 로 수집 dirname "${BASH_SOURCE[0]}"하고 하위 쉘에서 -ing을 실행하여 상위 쉘이 변경되지 않도록 한다는 cd것입니다 .$PWD

답변1

을 입력하면 $(...)처음부터 인용이 시작됩니다.

즉, "..."$(...)둥지서로 안에. 명령 대체는 $(...)하나 이상을 포함할 수 있습니다.충분히큰따옴표로 묶인 문자열입니다. 또한 큰따옴표로 묶인 문자열에는 하나 이상의 문자열이 포함될 수 있습니다.충분히명령 대체. 그러나 그들은 서로 얽혀 있지 않습니다. 따라서 명령 대체 내부에서 시작하는 큰따옴표 문자열은 명령 대체 외부로 확장되지 않으며 그 반대의 경우도 마찬가지입니다.

따라서 다음을 고려하십시오.

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

안에 들어있는 내용물은 $(...)다음과 같습니다.

dirname "${BASH_SOURCE[0]}"

위에는 ${BASH_SOURCE[0]}큰따옴표가 있습니다. 외부 큰따옴표나 작은따옴표는 큰따옴표인지 $(...)여부를 결정할 때 ${BASH_SOURCE[0]}관련이 없습니다 .

외부 레이어에는 다음이 $(...)포함됩니다.

cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd

여기서는 표현식을 $( dirname "${BASH_SOURCE[0]}" )큰따옴표로 묶습니다. $(...)외부에 인용문이 있다는 사실은 내부 내용을 고려할 때 관련이 없습니다. 내부에 따옴표가 있다는 사실 $(...)도 부적합합니다.

큰따옴표가 일치하는 방법은 다음과 같습니다.

여기에 이미지 설명을 입력하세요.

답변2

bash입력을 구문 분석하는 방법(및 일반적으로 쉘)에 대한 질문에 대한 혼란은 올바르지 않습니다. 존재하다:

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

먼저 bash과제의 오른쪽을 긴 문자열로 구문 분석합니다. $( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )큰따옴표가 내부에 나타날 수 있기 때문입니다.큰따옴표.

그런 다음 bash명령 대체 구문 분석을 시작합니다. 여는 대괄호와 닫는 대괄호 뒤의 모든 문자는 명령 대체에서 명령을 구성하는 데 사용되므로 다음과 같은 결과를 얻습니다.

cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd

셸은 계속해서 복합 명령을 구문 분석하여 두 부분으로 나눕니다.

  • cd "$( dirname "${BASH_SOURCE[0]}" )"
  • 비밀번호

그런 다음 동일한 구문 분석 규칙이 에 적용되지만 cd "$( dirname "${BASH_SOURCE[0]}" )"이번에는 큰따옴표가 중복되지 않고 의미가 있습니다. 이는 결과에서 필드 분할을 방지하며 $( dirname "${BASH_SOURCE[0]}" )( ${BASH_SOURCE[0]}가장 바깥쪽 큰따옴표와는 반대로)RHS에서 변수 할당을 방지할 필요가 없습니다.split+glob).


이 규칙은 다음에 적용됩니다.모든 POSIX 셸의 명령 대체. 퍼즐에 대한 자세한 내용을 읽을 수 있습니다.POSIX 사양의 토큰 인식 부분.

관련 정보