파일 글로브가 단어 분할의 영향을 받지 않는 이유는 무엇입니까?

파일 글로브가 단어 분할의 영향을 받지 않는 이유는 무엇입니까?

Bash 스크립트에서는 다음을 수행하는 것이 좋습니다.ls의 출력을 구문 분석하면 안 됩니다.

위에 링크된 웹페이지에서는 다음 코드를 권장합니다.

# Good!
for f in *; do
    [[ -e $f ]] || continue
    ...
done

또는 파일 이름으로 배열을 채웁니다.

myfiles=( ~/* )

그러나 예제를 보고 일반적으로 Bourne Shell이 ​​인용되지 않은 문자열을 어떻게 처리하는지 보면 공백이 포함된 파일 이름에 이 코드를 사용하면 glob이 모든 (공백으로 구분된) 단어를 폭발시킬 것 같은 느낌이 듭니다. 예를 들어 다음 디렉토리가 있는 경우

$ ls -1  
a file I downloaded from the net.pdf
apple.sh
hello world.txt

나는 이것을 실행한다

for file in *
    do printf "%s\n" "$file"
done

인용되지 않은 문자열 동작이 예상됩니다. 예를 들어

a
file
I
downloaded
from
the
net.pdf
apple
hello
world

하지만 내가 얻는 것은 올바른 행동입니다

a file I downloaded from the net.pdf
apple
hello world

배열과 유사

myfiles=( * )
declare -p myfiles
declare -a myfiles='([0]="a file I downloaded from the net.pdf" [1]="apple" [2]="hello world")'

내 질문은 이것이 왜일까요?
단어 분할 이후의 글로벌 확장 때문일까요? (이러한 유형의 파일 작업이 올바른 출력을 생성하도록 하기 위해?)

답변1

토큰화 후 파일 이름 확장이 발생합니다.

https://www.gnu.org/software/bash/manual/html_node/Shell-Expansions.html#Shell-Expansions

확장 순서는 중괄호 확장, 인수 및 변수 확장, 산술 확장, 명령 대체(왼쪽에서 오른쪽으로 수행)입니다.

답변2

[[ -e $f ]]특별한 경우이다. [[예약어는 서로 다른 규칙 사이 [[에서 유효합니다. ]]그 중 하나는 단어 분할을 수행하지 않습니다.

관련 정보