POSIX shell :`$`가 단어의 마지막 문자라면 특별한 의미를 잃어 버리나요? 내가 달릴 때 $ echo ab$ 그것은 반환 ab$ 이 동작이

애쉬, 대시, 배쉬에서 내가 달릴 때

$ echo ab$

그것은 반환

ab$

이 동작이 POSIX에 의해 지정 되었습니까 아니면 POSIX 호환 쉘에서 일반적인 규칙입니까? POSIX Shell Command Language 페이지에서이 동작을 언급 한 내용을 찾을 수 없습니다.



답변

$그 자체로 특별한 의미를 갖지 않으며 (try echo $), 그 후에 다른 캐릭터와 결합하여 확장을 형성 할 때만 $var( 예 : (또는 ${var}), $(util)) $((1+2)).

$섹션에서 POSIX 표준의 확장 정의로 의미의 “특별한”를 얻는다 토큰 인식을 :

현재 문자가 인용 부호가 $없거나 또는 인 `경우, 쉘은 각각 인용 부호가없는 문자 순서 ( $또는 ${, $(또는 `, 및) 로부터 매개 변수 확장, 명령 대체 또는 산술 확장 후보의 시작을 식별해야한다 $((. 쉘은 확장 될 장치의 끝을 결정하기에 충분한 입력 값을 읽어야 합니다 (인용 된 섹션에 설명 된대로)). 문자를 처리하는 동안 확장 또는 인용의 인스턴스가 대체 내에 중첩 된 것으로 발견되면 쉘은 발견 된 구문에 대해 지정된 방식으로 재귀 적으로 처리해야합니다. 포함 된 구성을 인식하는 데 필요한 재귀를 허용하는 대체의 시작부터 끝까지 발견 된 문자는 포함되거나 포함 된 대체 연산자 나 따옴표를 포함하여 결과 토큰에 수정되지 않은 상태로 포함되어야합니다. 토큰은 교체가 끝날 때까지 구분되지 않습니다.

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

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

그것은 당신의 ab$문자열을 다룹니다 .

고독한 경우 $(“새로운 단어”는 $그 자체 일 것임 ) :

현재 문자는 새로운 단어의 시작으로 사용됩니다.

표준 확장이 아닌를 포함하는 생성 된 단어 의 의미$POSIX에서 지정하지 않은 것으로 명시 적으로 정의됩니다.

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


답변

정확한 상황에 따라, 이것은 명시 적으로 지정되지 않았거나 (구현대로 구현할 수 있음) 관찰 한대로 발생해야합니다. 정확한 시나리오에서 echo ab$, POSIX는 관찰 된 것을 “AB $”출력을 의무화 하고 는 지정되지 않습니다 . 모든 다른 경우에 대한 간단한 요약이 끝났습니다.

먼저 단어로 토큰 화 한 다음 해당 단어를 해석하는 두 가지 요소가 있습니다.


토큰 화

POSIX의 tokenisation는 필요$ 유효한 개시 아니라고 파라미터 확장 , 명령 치환 또는 산술 교체 의 리터럴 부분 간주 WORD구성된 토큰된다. 규칙 5 ( “현재의 문자는 인용 부호가없는 경우 때문입니다 $`: 쉘이 자신의 소개 인용 부호로 둘러싸이지 않은 캐릭터 시퀀스에서 매개 변수 확장, 명령 치환, 또는 산술 확장에 대한 후보자의 시작을 식별해야한다 $${, $(`, 그리고 $((각각” )는 해당 확장이 실행 가능하지 않으므로 적용되지 않습니다. 매개 변수 확장에 유효한 이름이 나타나야하며 빈 이름이 유효하지 않습니다.

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

특별한 매개 변수의 이름이 아니기 echo a$+b때문에 동일한 균열을 겪는 형태의 세 번째 경우도 있습니다 +. 이것은 규칙의 다른 부분을 트리거하기 때문에 나중에 다시 돌아올 것입니다.

따라서, 명세서 $는 구문 적으로 단어의 일부로 간주 되어야하고, 이후에 추가로 처리 될 수 있어야한다.


단어 확장

이 방법으로 입력을 구문 분석 한 후 $단어에 단어를 포함 시키면 읽은 각 단어에 단어 확장 이 적용됩니다. 각 단어는 개별적 으로 처리 됩니다 .

다음과 같이 지정됩니다 .

따옴표없는 ‘$’뒤에 다음 중 하나가 아닌 문자가 오는 경우 :

  • 숫자
  • 특별한 매개 변수 중 하나의 이름은 (참조 특수 매개 변수 )
  • 변수 이름의 유효한 첫 문자
  • A <left-curly-bracket>( ‘{‘)
  • <left-parenthesis>

결과는 지정되어 있지 않습니다.

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

  1. 이 경우 적합한 쉘은 모든 동작을 선택할 수 있습니다
  2. 적합한 응용 프로그램 은 특정 동작에 의존 할 수 없습니다

당신의 예에서, echo ab$의는 $ 다음되지 않은 모든 문자를 이 규칙이 적용되지 않도록하고, 지정되지 않은 결과가 호출되지 않습니다. 에 의해 촉발 된 확장은 없으므로 $문자 그대로 존재하고 인쇄됩니다.

어디는 것입니다 적용 위에서 세 번째 경우이다 echo a$+b. 여기 $뒤에 +숫자, 특수 파라미터하지 않다 ( @, *, #, ?, -, $, !, 또는 0) 변수의 시작의 이름 (또는 언더에서 영 휴대용 문자 집합 ), 또는 하나의 브래킷. 이 경우 동작은 지정되지 않습니다. 적합한 쉘 +expand 라는 특수 매개 변수를 발명 할 수 있으며, 적합한 응용 프로그램 은 쉘이 그렇지 않다고 가정해서는 안됩니다 . 쉘은 오류보고를 포함하여 원하는 다른 작업을 수행 할 수 있습니다.

예를 들어 POSIX 모드를 포함하여 zsh 는 “변수 세트” 해석$+bb 하고 대신 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인수의 일환으로 명령을 실행합니다. 이것이 쉘의 적합성 요구 사항입니다.