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 ]]
특별한 경우이다. [[
예약어는 서로 다른 규칙 사이 [[
에서 유효합니다. ]]
그 중 하나는 단어 분할을 수행하지 않습니다.