확장 간의 순서를 이해하는 방법은 무엇입니까?

확장 간의 순서를 이해하는 방법은 무엇입니까?

POSIX 7부터 시작:

단어 확장 순서는 다음과 같습니다.

  1. 물결표 확장(섹션 2.6.1 참조), 매개변수 확장(섹션 2.6.2 참조), 명령 대체(섹션 2.6.3 참조) 및 산술 확장(섹션 2.6.4 참조)은 처음부터 끝까지 수행되어야 합니다. 섹션 2.3의 항목 5를 참조하세요.

  2. IFS가 비어 있지 않으면 1단계에서 생성된 필드 부분에 대해 필드 분할을 수행해야 합니다(섹션 2.6.5 참조).

  3. set -f가 적용되지 않는 한 경로 이름 확장이 수행되어야 합니다(섹션 2.6.6 참조).

  4. 견적 삭제(섹션 2.6.7 참조)는 항상 마지막에 수행되어야 합니다.

  1. 물결표 확장, 매개변수 확장, 명령 대체, 산술 확장이 지정된 순서대로 수행됩니까?

    그들 사이의 순서가 중요합니까? 그렇다면 왜 순서가 그대로인지 어떻게 알 수 있을까요?

  2. 필드 분할 후에 경로 이름 확장이 발생하고 필드 분할 전에 다른 확장이 발생하는 이유는 무엇입니까?

    특히 물결표 확장과 경로 이름 확장은 모두 경로 이름 및 파일 이름과 관련이 있는데, 필드 분할 측면에서 다르게 배치되는 이유는 무엇입니까?

  3. POSIX에 중괄호 확장이 없나요?

  4. "단어 확장"에 주목했습니다. 확장 프로그램은 토큰 식별자가 WORD인 토큰에만 적용되고 다른 토큰 식별자(예: NAME, 특정 연산자, NEWLINE, IO_NUMBER, ASSIGNMENT)가 있는 토큰에는 적용되지 않나요?

답변1

물결표 확장, 매개변수 확장, 명령 대체 및 산술 확장이 동일한 단계에 나열됩니다. 처형됐다는 뜻이다.동시에. 물결표 확장의 결과는 매개변수 확장을 거치지 않고, 매개변수 확장의 결과는 물결표 확장을 거치지 않습니다. 예를 들어, 값이 이면 foo단어 $(bar) qux는 1단계에서 확장됩니다 $foo. $(bar) qux매개변수 확장에 의해 생성된 텍스트는 1단계에서 더 이상의 변환을 거치지 않고 2단계에서 분할됩니다.

"시작에서 끝까지"는 왼쪽에서 오른쪽으로 처리하는 것을 의미합니다. 예를 들어 할당이 발생할 때 중요합니다: a=1; echo $a$((a=2))$a인쇄. 산술 확장은 첫 번째 인수 확장과 두 번째 인수 확장( 1222로 설정됨) 사이에서 수행되기 때문입니다.$((a=2))a$a$a

이 순서의 이유는 과거의 사용법 때문입니다. POSIX는 일반적으로 기존 구현을 따르며 새로운 동작을 거의 지정하지 않습니다. 대부분의 경우 POSIX는 여러 개의 쉘을 따릅니다.코헨 쉘그러나 존재하지 않는 대부분의 기능을 생략합니다.본 쉘(Bourne 쉘은 대부분 더 이상 사용되지 않으므로 POSIX의 다음 버전에는 새로운 ksh 기능이 포함될 수 있습니다.)

Bourne 쉘이 매개변수 확장, 필드 분할 및 와일드카드를 수행하는 이유는 와일드카드를 변수에 저장할 수 있기 때문입니다. 일치를 나타내는 파일 이름 목록을 a설정 *.txt *.pdf한 다음 사용할 수 있고 이름 목록 일치가 뒤따릅니다 (두 패턴이 일치한다고 가정). ). (이것이 최고의 디자인이라고 말하는 것은 아닙니다. 단지 그렇게 설계되었다는 것뿐입니다.) 사람들이 Korn 쉘의 특정 단계에 명령 대체를 배치하려는 이유가 무엇인지 잘 모르겠습니다 . 매개변수 확장에 가깝기 때문에 함께 실행하는 것이 합리적입니다.$a*.txt*.pdf$(…)${…}

물결표 확장의 위치는 역사적으로 이상합니다. ~$some_user이름이 value 변수인 사용자의 홈 디렉터리에 쓰고 확장할 수 있도록 나중에 배치하는 것이 더 합리적입니다 some_user. 왜 안되는지 모르겠습니다. 이 명령에는 물결표 확장의 결과가 다른 확장의 영향을 받지 않는다는 특수 명령문도 필요합니다(인용한 구절에 따르면, 그렇다면 HOME두 단어로 확장되고 필드 분할로 인해 확장되지만 쉘 은 이를 수행하지 않습니다 /foo bar) , POSIX .2008에서는 "물결표 확장으로 생성된 경로 이름은 인용 부호로 처리되어야 합니다"라고 명시적으로 명시하고 있습니다.~/foobar

POSIX에는 중괄호 확장이 없습니다. 그렇지 않으면 사양에서 이를 명시합니다.

단어 확장은 WORD에서만 수행됩니다. 다음 섹션에 언급된 주의 사항이 있습니다(예: 필드 분할 및 경로 이름 생성은 여러 단어가 허용되는 컨텍스트에서만 수행됩니다(예: 큰따옴표 사이에는 수행되지 않음). NAME, NEWLINE, IO_NUMBER 등에는 확장할 수 있는 항목이 포함되어 있지 않습니다.

답변2

(1)과 관련하여 이 시퀀스는 기존 구현을 기반으로 합니다. 글을 쓰는 사람이 다른 껍질에 대한 다른 주문이 고려된다는 것을 알고 있다면기준, 그들은 이것을 허용하기 위해 문구에 약간의 여유를 제공할 것입니다. 에서 언급했듯이2.6 단어 확장, 다른 주문이 이 표준을 충족할 수 있다는 징후는 없습니다.

다시 말하지만, (2)의 경우 이는 기존 구현을 기반으로 한다는 점을 기억하세요. 몇 가지 흥미로운 차이점 영역(예: BSD 대 SVr4)이 있지만 원래 구현에 대한 이유를 표준에서 반드시 찾을 수는 없습니다.이유이 섹션에서는 위원회가 상충되는 대안 중 하나를 선택한 이유를 요약합니다.

(3)의 경우 언급한 "중괄호 확장"은 다음과 관련이 있을 수 있습니다.2.6.2 매개변수 확장(POSIX에서는 반드시 그런 것은 아니지만 다른 가능성도 있습니다).

마지막으로 (4),기억하다하나NAME어떤 종류인가WORD. 단어 확장이 적용됩니다.이름.

답변3

  1. 처음 4개의 확장 주문:

트리거는 물결표 확장 ~, 매개변수 확장 $name및 합계 ${name}, 명령 대체 합계 $(), ` `산술 확장 등 각 확장마다 다릅니다 $((...))). 따라서 하나의 확장을 다른 확장과 혼동할 수 없고 각 확장은 한 번만 실행되므로 순서는 중요하지 않습니다. 매개변수 확장을 수행한 토큰은 명령 대체를 수행하지 않습니다(예:).
혼란스러울 수 있는 확장 유형 중 하나는 산술 확장입니다. 그 안에는 매개변수 확장, 확장, 문자열 확장, 명령 대체 및 따옴표 제거가 있을 수 있기 때문입니다. 또한 산술 확장은 중첩될 수 있습니다. 하지만 이 모든 일은 감지된 산술 확장 내부에서 발생하며 외부가 아닙니다.

가장 중요한 순서는 왼쪽에서 오른쪽입니다.

결국 위 확장의 결과(인용되지 않은 경우)는 필드 분할 및 경로 이름 확장(순서대로)의 영향을 받습니다.

모든 확장 프로그램은 결국 제안에서 제거됩니다.

  1. 아니요, POSIX에는 중괄호 확장이 없습니다.
  2. 이 경우 단어와 마크는 동일한 개념을 나타내는 경우가 많습니다.

관련 정보