빈 문자열을 초래하는 매개 변수 확장은 다르게 처리됩니다.


10

최신 정보

누군가 버그 배쉬 메일 링리스트가 있습니다 확인 이 버그입니다.


관심이 있으시면 최신 분기 개발을 위해 수정 사항을 사용할 수 있습니다 .


동안

bash -c 'echo "${1##*""}"' _ bar

빈 줄을 인쇄하고

bash -c 'echo "${1##*"${1##*}"}"' _ bar

인쇄합니다 bar.

나는 이것을 이해하지 못한다. ${1##*}빈 문자열로 확장되므로 "${1##*}"그대로 취급해야 ""하지만 bash는 그렇게 생각하지 않는 것 같습니다.

다른 인기있는 sh구현 중 이것에 대한 합의가있는 것 같습니다 .

$ sh -c 'echo "${1##*"${1##*}"}"' _ bar

$ ash -c 'echo "${1##*"${1##*}"}"' _ bar

$ dash -c 'echo "${1##*"${1##*}"}"' _ bar

$ ksh -c 'echo "${1##*"${1##*}"}"' _ bar

$ ksh93 -c 'echo "${1##*"${1##*}"}"' _ bar

$ mksh -c 'echo "${1##*"${1##*}"}"' _ bar

$ posh -c 'echo "${1##*"${1##*}"}"' _ bar

$ yash -c 'echo "${1##*"${1##*}"}"' _ bar

$ zsh -c 'echo "${1##*"${1##*}"}"' _ bar

$

bash (유무에 관계없이 --posix)는 그것을 준수하지 않는 유일한 것입니다.

$ bash -c 'echo "${1##*"${1##*}"}"' _ bar
bar

그리고 부분 문자열 처리가 없으면 동작은 예상대로입니다.

$ bash -c 'echo "${1##*"${1+}"}"' _ bar

$ bash -c 'echo "${1##*"${2}"}"' _ bar

$ bash -c 'echo "${1##*"${2}"}"' _ bar ''

$ 

나는 이것에 대한 설명이 있는지 궁금합니다. 매뉴얼에서 찾을 수 없었습니다. 이것이 버그입니까, 아니면 표준을 잘못 해석합니까? 이 행동은 어딘가에 기록되어 있습니까?


추신 : 빠른 해결 방법은 내부 PE를 인용하지 않는 것이지만 내 질문에 대답하지 않으며 특수 문자가 포함 된 문자열로 원하지 않는 결과를 초래할 수 있습니다.


GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)빈 문자열을 인쇄
— 윌리엄 Pursell

GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)"bar"인쇄
— William Pursell 13:30에

4.4.20 및 5.0.11와 모두 인쇄 "바"테스트 @William
— 이스마일 오구 즈

이것은 일반적으로 확장에 문제가있는 것 같습니다. 내 4.4.12(3)-release에서 echo "${BASH##*"${BASH##*}"}"-> /bin/bash. 동안 echo "\${BASH##*"${BASH##*}"}"-> ${BASH##*}와 eval echo "\${BASH##*"${BASH##*}"}"-> 빈.
— Jeff Y

답변:


2

이것은 대답이 아닙니다

처음에는 이것이 특별한 glob-rules 때문이라고 생각했지만 결국 이것은 bash의 버그라고 생각합니다. 다음 네 가지 예는 이것이 이것이 버그라고 생각하는 이유를 알려줍니다.

$ bash -c 'echo "${1##*${1%%bar}}"' _ foobar        # case 1
bar
$ bash -c 'echo "${1##*${1%%foobar}}"' _ foobar     # case 2

$ bash -c 'echo "${1##*"${1%%bar}"}"' _ foobar      # case 3
bar
$ bash -c 'echo "${1##*"${1%%foobar}"}"' _ foobar   # case 4
foobar

사례 1과 사례 3은 따옴표가 다릅니다. 그러나 형식의 매개 변수 확장은 ${parameter##word}경로 이름 확장 규칙을 사용하여 처리 word합니다. 그래서 *foo그리고 *"foo"그들은 특수 패턴 문자를 수용하지 않는 경로 확장에 큰 따옴표와 같은 동일한 동작이 무시 될 수있다 ( *, ?, ...). 이것은 다음 예제에서 볼 수 있습니다.

$ bash -c 'echo "${1##*${2%%b*r}}"' _ 'foobar' 'f*ob*r'
bar
$ bash -c 'echo "${1##*"${2%%b*r}"}"' _ 'foobar' 'f*ob*r'
foobar

그렇다면 이것이 사례 2와 사례 4가 다르게 행동해야하는 이유는 무엇입니까?


사례 2와 사례 4가 다르게 행동해야하는 이유는 무엇입니까? 어떤 이유로, 모두 ${1+}와 ${1+""}팽창은 문자열을 비울 수 없습니다, 그러나이 방법은 처리되지 않습니다 ${1##*}(내 최신 편집 참조). 따라서 우리는 이것이 버그라고 추론 할 수 있습니다.
— oguz ismail

1
@oguzismail 정확히! 사례 1과 사례 3이 동일하게 작동하면 사례 2와 사례 4도 동일하게 작동해야합니다.
— kvantour
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.