POSIX에 "${1-"$var"}"(아래 옵션 6)에 대한 언급이 없는 이유는 무엇입니까?

POSIX에 "${1-"$var"}"(아래 옵션 6)에 대한 언급이 없는 이유는 무엇입니까?

내가 찾을 수 있는 유일한 참고자료이것은 사양입니다:

"$()"에 대한 명령문과 유사하게 "동봉된 "${"에서 일치하는 "}"까지의 문자는 큰따옴표의 영향을 받지 않아야 합니다."와 같은 명령문을 포함하는 것이 좋습니다. 그러나 System V 셸의 역사적 관행으로 인해 이를 방지할 수 있습니다.

분명한 질문은 "그 역사적 질문은 무엇이었는가"이며, 더 중요한 것은 그것이 오늘날 우리에게 어떤 영향을 미치는가입니다.

C.2.5 Parameters and Variables이 페이지 제목 아래에는 인용 확장의 예가 많이 있으며, 모두 나열하기 위해 최선을 다한 것 같지만 큰따옴표가 두 번 나타나는 예는 없습니다 .

설명하다

문제는 다음 6가지 인용 대안의 결과와 관련이 있습니다.

  • $b, "$b", ${a-$b}, ${a-"$b"} "${a-$b}"그리고"${a-"$b"}"

처음 5개는 POSIX에 의해 정의되며 일부 쉘은 이러한 확장의 결과에 동의합니다. 일부 값은 다음 값을 기준으로 분할됩니다 $IFS.

$ export a=abc; for sh in dash ksh93 bash; do $sh -c 'IFS="bl"; b=value 
  printf "<%s> " 1$b 2"$b" 3${a-$b} 4${a-"$b"} 5"${a-$b}" 6"${a-"$b"}";
  echo'; done

<1va> <ue> <2value> <3a> <c> <4a> <c> <5abc> <6abc> 
<1va> <ue> <2value> <3a> <c> <4a> <c> <5abc> <6abc> 
<1va> <ue> <2value> <3a> <c> <4a> <c> <5abc> <6abc>

하지만 "${1-"$var"}"사양 어딘가에 정의되어 있습니까?

즉,반복하다큰따옴표(외부 및 내부)

추가 1

관련 정보로 다음 결과를 살펴보십시오. 이전 코드와 다음 코드의 유일한 차이점은 $a설정되지 않았다는 것입니다.

$ unset a; for sh in dash ksh93 bash; do $sh -c 'IFS="bl"; b=value 
  printf "<%s> " 1$b 2"$b" 3${a-$b} 4${a-"$b"} 5"${a-$b}" 6"${a-"$b"}";
  echo'; done

<1va> <ue> <2value> <3va> <ue> <4value> <5value> <6value> 
<1va> <ue> <2value> <3va> <ue> <4value> <5value> <6va> <ue> 
<1va> <ue> <2value> <3va> <ue> <4value> <5value> <6value>

추가 2

실제로 모든 인용 옵션을 테스트할 때 일반 쉘은 충돌하는 방식으로 작동합니다.

$ for sh in dash ksh93 bash; do $sh -c 'IFS="bl"; b=value 
  printf "<%s> " 1\n 2"\n" 3${a-\n} 4${a-"\n"} 5"${a-\n}" 6"${a-"\n"}";
  echo'; done

<1n> <2\n> <3n> <4\n> <5\n> <6\n> 
<1n> <2\n> <3n> <4\n> <5\n> <6n> 
<1n> <2\n> <3n> <4\n> <5\n> <6n>

여기에는 zsh도 포함되지 않습니다!.

답변1

POSIX에서는 왜 "${1-"$var"}"언급되지 않습니까?

확장 프로그램 내부와 외부에 따옴표가 있다는 것이 무엇을 의미하는지 전혀 명확하지 않은 것 같고 정의되지 않도록 승인된 변경 사항이 있는 것 같습니다.

그러나 확장 외부에서 따옴표를 사용하는 것이 일반적입니다. 이는 단어(필드) 분할 및 와일드카드를 방지하기 위해 수행하는 작업입니다. 확장 기능에 넣는 것에 대한 언급도 있습니다.

부분2.2.3 큰따옴표설명하다

큰따옴표( "")로 묶인 문자는 다음과 같이 백틱, <달러 기호> 및 <백슬래시> 문자를 제외하고 큰따옴표 안의 모든 문자의 리터럴 값을 유지합니다.

${[...] 일치하는 대괄호의 문자열에서 },이스케이프 처리되지 않은 짝수 개의 큰따옴표또는 작은따옴표(있는 경우)가 있어야 합니다.

명령 대체의 경우 다음과 같습니다.

인용된 문자열의 입력 문자는 및 사이에도 포함되며 $(일치 항목은 )큰따옴표로 묶어서는 안 됩니다. [...]

매개변수 확장에는 이에 대한 언급이 없으므로 내부 문자 ${...}도 외부 따옴표의 영향을 받는다는 의미입니다.

${foo-\n}vs.(사례 3과 5)의 예는 "${foo-\n}"실제로 vs. \n와 마찬가지로 외부 따옴표가 백슬래시를 보호한다는 것을 보여줍니다."\n"


하지만 내부 인용문과 외부 인용문을 모두 언급하지 않는 것 같고, 무엇을 해야 할지 명확하지 않습니다.

내부 문자가 외부 따옴표의 영향을 받는 경우 가능한 설명 중 하나는 첫 번째 내부 큰 따옴표입니다.마치다참조하면 두 번째는 이를 다시 시작한 다음 whatever역참조합니다. Ksh는 다음과 같이 이 해석을 상당히 일관되게 따르는 것 같습니다.

$ printf "<%s>\n" "${foo-"foo \n *"}"
<foo>
<n>
<file1.txt>
<file2.txt>

이것이 매우 유용한지는 잘 모르겠고, 이 작업을 수행하는 다른 쉘도 거의 없습니다. (적어도 최근에 시도한 것들로 판단하면.)

<foo \n *>다른 경우에는 문자열이 완전히 인용된 것처럼, 내부 큰따옴표가 단순히 문자를 인용해야 한다는 사실을 강조하는 것처럼 출력의 대부분이 단지 입니다 .

그런 다음 Bash와 Dash는 백슬래시를 일관되지 않은 방식으로 처리하는 것 같고 인쇄는 <foo n *>내가 생각할 수 있는 논리적 규칙을 따르지 않는 것 같습니다. \n마치 인용되지 않은 것처럼 동작하는 반면 *및 공백은 마치 인용된 것처럼 동작합니다.

넣으면 더 털이 날 것 같아요하나의인용 부호.


이러한 불일치를 목격하면서 이 문제가 이전에 논의된 것은 아마도 놀라운 일이 아닐 것입니다.이를 명시적으로 정의되지 않게 만드는 보류 중인 변경 사항이 있는 것 같습니다., 관련 부분은 다음과 같습니다.

하위 문자열 처리를 제공하는 네 가지 유형 이외의 매개변수 확장의 경우 확장이 발생하는 큰따옴표는 둘러싸는 "${"에서 일치하는 "}"까지 문자열의 모든 문자의 리터럴 값을 유지해야 합니다. 큰따옴표, 역따옴표 및. 문자열에 이스케이프 처리되지 않은 큰따옴표 문자가 있으면 동작이 지정되지 않습니다(내장된 명령 대체 제외).

그리고

셸 구현은 "${...}" 내에서 이스케이프 처리되지 않은 큰따옴표 문자를 처리하는 방법에 따라 매우 다양합니다(4개의 하위 문자열 처리 변형 제외). 따라서 표준은 동작을 지정하지 않습니다. [...] "${...}" 형식 처리의 차이로 인해 System V 쉘, BSD 및 KornShell 간의 역사적 불일치가 발생했습니다. POSIX.1-2008의 쉘 및 유틸리티 볼륨에 있는 텍스트는 다음과 같습니다. 너무 많은 응용 프로그램을 중단하지 않고 혼합을 시도하십시오.

이것이 역사적인 이유인 것 같습니다.

첫 번째 내용을 읽는 방식은 ${foo-"bar"}단지 가 아니라 또한 의미하는 것 같습니다 "${foo-"bar"}". 전자는 쉘 간에 다른 결과를 제공하는 경향이 덜한 것 같습니다.

2010년에는 이에 대한 논의를 찾지 못했지만, 작은 따옴표의 작동 방식을 다루는 2016년의 메시지는 다음과 같습니다.

로버트 에르츠:

인용된 ${ }는 쉘의 [가장 털이 많은] 부분 중 하나이며 어떤 의미에서 가장 무섭고 재현하기가 정말 어렵습니다. 이 모든 것이 지정되지 않았거나 문제가 될 것이라는 것은 놀라운 일이 아닙니다 8(아직 이해할 수 없음).

쳇 레이미:

좋아요 Geoff의 입장은 Issue 7 텍스트가 셸이 아닌 애플리케이션에 대한 요구 사항이며, 더 나아가 작은 따옴표와 큰 따옴표 각각의 의도에 대해 요구 사항이 모호하게 표현되어 있다는 것입니다(즉, 중첩될 수 없음).

따라서 해석 221을 논의할 때 정확하다고 지적할 수 있는 쉘 동작은 없으며 논의의 일부에는 무엇이 올바른지 결정하고 이를 명확하게 표현하는 것이 포함됩니다.

관련 정보