이 작은 설정이 나를 미치게 만듭니다.
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?
nullglob
foo
즉, 이 설정은 (현재 디렉토리의 파일을 호출하지 않는 한 nullglob
) 따옴표가 없는 단어라도 배열의 요소로 지정되는 것을 방지합니다.bar?
bar?
두 개의 문자열을 배열로 원하는 경우 이를 인용하는 것이 해결책입니다( foo
인용 은 필요하지 않지만 일관성을 유지하는 데에는 문제가 없습니다).bar?
foo
array=('foo' 'bar?')
이 문제를 "해결"하는 또 다른 방법은 다음과 같습니다.장애를 입히다파일 이름 와일드카드. 이는 다음을 통해 수행됩니다 set -f
.
set -f
array=(foo bar?)
set +f
아마도 Michael이 보여주고 싶었던 것은 array=(*)
따옴표가 없는 값(여기서는 따옴표가 없는 값 *
)의 글로빙이 발생한다는 것입니다. 그는 이것이 문제의 근원이기 때문에 이것을 보여주고 싶었습니다.