3.5K 이상의 투표가 포함 된 StackOverflow 답변DIR
에는 현재 bash 스크립트의 디렉토리에 할당 할 수 있는 이 한 줄짜리 기능이 있습니다.
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
중첩 된 큰 따옴표에 의아해합니다. 내가 알 수있는 한 다음 조각은 큰 따옴표로 묶습니다.
"$( cd "
"${BASH_SOURCE[0]}"
" && pwd )"
… 그리고 오른쪽에있는 다른 모든 =
(즉, $( dirname
와 )
) 인용 부호로 둘러싸입니다. 즉, 두 번째, 네 번째 및 여섯 "
번째 "
문자는 각각 첫 번째, 세 번째 및 다섯 번째 문자를 “닫습니다” 라고 가정합니다 .
큰 따옴표가 "${BASH_SOURCE[0]}"
무엇 을 달성 하는지 이해 하지만 다른 두 따옴표의 목적은 무엇입니까?
반면에 (그리고 높은 투표 점수에도 불구하고) 위의 스 니펫이 잘못된 경우 명목상의 의도를 달성하는 올바른 방법은 무엇입니까?
( 공칭 의도로 나는 의미합니다 :을 반환 한 디렉토리에 pwd
처음 cd
-ing 한 후 반환 된 값을 수집하고 하위 셸에서 -ing을 dirname "${BASH_SOURCE[0]}"
수행 하여 상위 셸의 값을 변경 하지 마십시오 ).cd
$PWD
답변
당신의 퍼즐은 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는 변수 할당의 RHS에서 필요하지 않습니다split+glob
).
이 규칙 은 모든 POSIX 쉘에서 명령 대체에 적용됩니다 . POSIX 사양의 토큰 인식 섹션 에서 더 자세한 퍼즐을 읽을 수 있습니다 .
답변
안에 들어가면 $(...)
인용문이 처음부터 다시 시작됩니다.
즉, "..."
과 $(...)
깡통 둥지 서로 내. 프로세스 대체 $(...)
에는 하나 이상의 완전한 큰 따옴표로 묶인 문자열이 포함될 수 있습니다 . 또한 큰 따옴표로 묶인 문자열에는 하나 이상의 완전한 프로세스 대체 가 포함될 수 있습니다 . 그러나 인터레이스하지 않습니다. 따라서 프로세스 대체 내부에서 시작하는 큰 따옴표로 묶인 문자열은 절대로 그 외부로 확장되거나 그 반대로 확장되지 않습니다.
따라서 다음을 고려하십시오.
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]}" )
은 큰 따옴표로 묶습니다. 외부에 따옴표가 있다는 사실 $(...)
은 내부에 무엇이 있는지 고려할 때 관련이 없습니다. 내부에 따옴표가 있다는 사실 $(...)
도 관련이 없습니다.
큰 따옴표가 일치하는 방법은 다음과 같습니다.