POSIX 쉘: 단어의 마지막 문자인 경우 "$"가 특별한 의미를 잃습니까?

POSIX 쉘: 단어의 마지막 문자인 경우 "$"가 특별한 의미를 잃습니까?

내가 달릴 때, Ashes, Sprints 및 Slams에서

$ echo ab$

그것은 돌아온다

ab$

이 동작은 POSIX에 의해 지정됩니까, 아니면 POSIX 호환 셸 간의 일반적인 규칙입니까? POSIX Shell Command Language 페이지에서 이 동작에 대한 언급을 찾을 수 없습니다.

답변1

$그 자체로는 특별한 의미가 없습니다(try ). (또는 ) ,, echo $와 같은 다른 후속 문자와 결합하여 확장자를 형성할 때만 특별한 의미가 있습니다 .$var${var}$(util)$((1+2))

"특별한" 의미 $는 확장이 POSIX 표준에 정의되어 있다는 것입니다.토큰 인식:

현재 문자가 따옴표가 없는 $or 인 경우 `쉘은 따옴표가 없는 소개 문자 시퀀스 $인 or ${, $(또는 `, 및 에서 매개변수 확장, 명령 대체 또는 산술 확장에 대한 후보의 시작을 식별해야 합니다 $((. 쉘은 확장할 장치의 끝을 결정하기에 충분한 입력을 읽어야 합니다(인용된 장에서 설명했듯이). 문자를 처리할 때 중첩된 확장 또는 인용 인스턴스가 대체에서 발견되면 쉘은 발견된 구성에 대해 지정된 대로 이를 반복적으로 처리해야 합니다. 대체 시작부터 끝까지 발견된 문자(내장된 구조를 식별하는 데 필요한 재귀를 허용)는 포함되거나 포함된 대체 연산자 또는 따옴표를 포함하여 수정되지 않은 결과 마크업에 포함되어야 합니다. 토큰은 대체가 끝날 때까지 구분되어서는 안 됩니다.

따라서 $확장이 형성되지 않으면 다른 구문 분석 규칙이 적용됩니다.

이전 문자가 단어의 일부인 경우 현재 문자가 해당 단어에 추가되어야 합니다.

그것은 당신의 ab$끈을 덮습니다.

별도의 경우 $("새 단어" $자체는 다음과 같습니다):

현재 문자가 새 단어의 시작 부분으로 사용됩니다.

이것중요성$비표준 확장을 포함하는 생성된 단어는 POSIX에서 명시적으로 지정되지 않음으로 정의됩니다.

또한 $의 마지막 문자는 이지만 $$이는 현재 쉘의 PID를 보유하는 변수이기도 합니다. 에서는 bash히스토리 !$확장을 호출할 수 있습니다(이전 명령의 마지막 인수). 따라서 일반적으로 아니요, $인용되지 않은 단어의 끝은 의미가 없지만 단어의 끝은 적어도 표준 확장을 의미하지 않습니다.

답변2

상황에 따라 이는 명시적으로 지정되지 않거나(구현이 원하는 대로 수행될 수 있음) 관찰한 방식으로 발생해야 합니다. 특정 시나리오 echo ab$에서는POSIX는 관찰한 "ab$"의 출력을 강제합니다.그리고이는 지정되지 않았습니다.. 마지막으로 다양한 사례에 대한 간략한 요약입니다.

두 가지 요소가 있습니다. 먼저 단어로 레이블을 지정하고 해당 단어를 해석하는 것입니다.


토큰화

POSIX 토큰화 요구 사항A는 $유효한 시작이 아닙니다.매개변수 확장,명령 대체, 또는산술 대체WORD생성되는 토큰의 문자 그대로의 일부로 처리됩니다 . 이는 규칙 5 때문입니다("현재 문자가 따옴표가 없는 $or 이면 `쉘은 따옴표가 없는 소개 문자 시퀀스에서 매개변수 확장, 명령 대체 또는 산술 확장에 대한 후보의 시작을 식별해야 합니다: $또는 ${, 각각 $(또는 `, $((" ) 여기서는 이러한 확장이 불가능하므로 적용하지 마세요. 매개변수 확장에는 유효한 이름이 있어야 하며, 빈 이름은 유효하지 않습니다.

이 규칙은 적용되지 않으므로 적용되는 규칙을 찾을 때까지 계속해서 이를 따를 것입니다. 두 가지 후보는 #8("이전 문자가 단어의 일부인 경우 현재 문자가 해당 단어에 추가되어야 합니다.")과 #10("현재 문자가 새 단어의 시작으로 사용됩니다.")입니다. 각각 echo a$및 에 적용됩니다 echo $.

세 번째 형태도 특별한 매개변수의 이름이 아니기 echo a$+b때문에 같은 상황에 속한다 . +규칙의 다른 부분을 트리거하므로 이에 대해 나중에 다시 설명하겠습니다.

따라서 사양에서는 $문법적으로 단어의 일부로 처리되어 나중에 추가로 처리될 수 있도록 요구합니다.


단어 확장

이런 식으로 입력을 구문 분석하고 $이를 단어로 포함시킨 후,단어 확장읽은 모든 단어에 적용됩니다. 모든 단어가 처리됩니다.개별적으로.

명확하게 정의됨:

따옴표가 없는 "$" 뒤에 다음 문자 중 하나 이외의 문자가 오는 경우:

  • 숫자
  • 특수 매개변수 중 하나의 이름(참조:특수 매개변수)
  • 변수 이름의 유효한 첫 번째 문자
  • <left-curly-bracket>('{')
  • <left-parenthesis>

결과가 지정되지 않았습니다.

여기서 "지정되지 않음"은 특별한 용어입니다.

  1. 이 경우 일관된 쉘은 모든 동작을 선택할 수 있습니다.
  2. 자격을 갖춘애플리케이션특정 행동에 의존할 수 없음

귀하의 예 echo ab$에서는$ 뒤처지지 않음어느특징이므로 규칙이 적용되지 않으며 지정되지 않은 결과가 호출되지 않습니다. 전혀 확장이 발생하지 않았 $으므로 존재하고 인쇄됩니다.

어디회의위의 세 번째 경우에 적용되는 것은 다음과 같습니다 echo a$+b. 뒤에 , 숫자 $+아님, 특수 매개변수( @, *, #, ?, -, $또는 !) 0, 변수의 시작이름(밑줄 또는 문자휴대용 문자 세트) 또는 대괄호 중 하나입니다. 이 경우 동작은 지정되지 않습니다. 일관된 쉘+확장이라는 특별한 매개변수를 고안하는 것이 허용되었습니다.및 적격 신청서쉘이 그렇지 않다고 가정해서는 안됩니다.. 쉘은 오류 보고를 포함하여 원하는 모든 작업을 수행할 수도 있습니다.

예를 들어 POSIX 모드를 포함한 zsh는" 변수의 집합" $+b으로 해석됩니다 .b그리고 그 자리를 1이나 0으로 바꿉니다. 또한 ~및 에 대한 확장도 있습니다 =. 이는 규정을 준수하는 동작입니다.

이런 일이 일어날 수 있는 또 다른 곳은 입니다 echo "a$ b". 다시 말하지만, 쉘은 원하는 것을 수행할 수 있으며 스크립트 작성자로서 $리터럴 출력을 원한다면 이스케이프해야 합니다. 그렇지 않으면 효과가 있을 수 있지만 의존할 수는 없습니다. 이는 사양의 절대적인 문자이지만 이러한 세분성은 의도적이거나 고려된 것이 아니라고 생각합니다.


요컨대

  • echo ab$:텍스트 출력, 완전히 지정됨
  • echo a$ b:텍스트 출력, 완전히 지정됨
  • echo a$ b$:텍스트 출력, 완전히 지정됨
  • echo a$b: 매개변수 확장 b, 완전히 지정됨
  • echo a$-b:특수 매개변수 확장 -, 완전히 지정됨
  • echo a$+b: 지정되지 않은 동작
  • echo "a$ b": 지정되지 않은 동작

$단어 끝의 a 에 대한 해당 동작을 신뢰할 수 있으며 문자 그대로 처리하고 echo인수의 일부로 명령에 전달해야 합니다. 이는 셸에 대한 일관성 요구 사항입니다.

관련 정보