shopt -s nullglob이 배열 요소에 물음표가 있는 문자열을 제거하는 이유는 무엇입니까?

shopt -s nullglob이 배열 요소에 물음표가 있는 문자열을 제거하는 이유는 무엇입니까?

이 작은 설정이 나를 미치게 만듭니다.

shopt -s nullglob

나는 이것을 bash 4.3 스크립트에서 전역 설정으로 사용하고 있습니다.빈 디렉터리를 스캔할 때 오류 방지.

이제 이해할 수 없는 이상한 문제를 발견했습니다.

# shopt -s nullglob
# array=(foo bar)
# echo "${array[@]}"
foo bar
# array=(foo bar?)
# echo "${array[@]}"
foo
# shopt -u nullglob
# array=(foo bar)
# echo "${array[@]}"
foo bar
# array=(foo bar?)
# echo "${array[@]}"
foo bar?

보시다시피 bar?배열 요소에서 제거되었습니다. 그런데 왜 그럴까요? 이것문서*및 를 포함할 수 있는 파일 이름 패턴을 참조 ?하지만 별도의 배열은 "일치하지 않는 파일"과 관련이 없습니다.

If set, Bash allows filename patterns which match no files to expand to a null string, rather than themselves.

이것은 버그입니까?

PS 내 문제를 해결하기 위해 루프 주위에 nullglob을 설정/설정 해제하겠습니다. 이것은 문제가 되지 않습니다!

업데이트 1

@MichaelHomer의 요청에 따라:

# shopt -s nullglob
# array=(*)
# echo "${array[@]}"
1 Video_folder Server bin config dev etc etc.defaults initrd lib lib32 lib64 lost+found mnt proc root run sbin storage sys tmp tmpRoot usr var var.defaults volume1
# shopt -u nullglob
# array=(*)
# echo "${array[@]}"
1 Video_folder Server bin config dev etc etc.defaults initrd lib lib32 lib64 lost+found mnt proc root run sbin storage sys tmp tmpRoot usr var var.defaults volume1

이게 무슨 뜻이야?

답변1

이렇게 하면 array=(foo bar?)문자열 bar?이 인용되지 않고 파일 이름 와일드카드 문자 ?(모든 단일 문자와 일치)를 포함합니다. 이는 쉘이 이 값에 대해 파일 이름 글로빙을 수행한다는 것을 의미합니다. 패턴이 아무것도 일치하지 않으면 기본값은 그대로 두는 것입니다. 일치하는 항목(예: bar1등) 이 있으면 bar-일치 bar.하는 이름이 배열에 삽입됩니다.

활성화되면, 일치하는 파일 이름이 없으면 nullglob따옴표가 없는 globbing 패턴이 완전히 제거됩니다 (보통 사람들이 활성화하려는 이유가 바로 이것이기 때문입니다). 즉, 이 경우 배열에는 해당 요소만 포함됩니다.bar?nullglobfoo

즉, 이 설정은 (현재 디렉토리의 파일을 호출하지 않는 한 nullglob) 따옴표가 없는 단어라도 배열의 요소로 지정되는 것을 방지합니다.bar?bar?

두 개의 문자열을 배열로 원하는 경우 이를 인용하는 것이 해결책입니다( foo인용 은 필요하지 않지만 일관성을 유지하는 데에는 문제가 없습니다).bar?foo

array=('foo' 'bar?')

이 문제를 "해결"하는 또 다른 방법은 다음과 같습니다.장애를 입히다파일 이름 와일드카드. 이는 다음을 통해 수행됩니다 set -f.

set -f
array=(foo bar?)
set +f

아마도 Michael이 보여주고 싶었던 것은 array=(*)따옴표가 없는 값(여기서는 따옴표가 없는 값 *)의 글로빙이 발생한다는 것입니다. 그는 이것이 문제의 근원이기 때문에 이것을 보여주고 싶었습니다.

관련 정보