이 스크립트가 있습니다.
#!/bin/bash
function main {
while read -r file; do
do_something "$file"
done <<< $(find . -type f 2>/dev/null)
}
function do_something{
echo file:$@
}
Linux에서는 잘 작동하지만 Mac(Bash 버전 5.2)에서는 찾은 모든 파일을 하나의 항목으로 처리하고 줄 바꿈 없이 전체 문자열을 전달합니다 do_something
.
while read -r file; do
echo file:"$file"
done <<< $(find . -type f 2>/dev/null)
Mac의 Bash 터미널에서도 직접 잘 작동합니다. 그럼 무엇이 잘못됐나요?
답변1
이 문자열 연산자가 zsh에서 복사된 이전 버전의 bash에서는 <<< $param$((arith))$(cmdsubst)
따옴표 <<<
가 없는 확장이 -splitting의 영향을 받았으며 $IFS
결과 단어가 공백과 연결되어 결과가 대상의 임시 파일로 전달되는 작성에 저장되었습니다.
이 문제는 4.4에서 수정되었습니다. 바라보다CWRU/변경 로그의 해당 항목:
2015-09-02
redir.c
- write_here_string: 여기서 문자열 문서를 토큰화하지 마세요. bash 문서에서는 bash가 수년 동안 이 작업을 수행해 왔고 여기에서 문자열을 구현하는 다른 쉘이 어떤 토큰화도 수행하지 않음에도 불구하고 항상 이런 일이 발생하지 않는다고 말합니다. 최종 효과는 IFS 문자 시퀀스가 공백으로 축소된다는 것입니다. Clint Hepner가 보고한 버그 수정<[이메일 보호됨]>
그러나 macOS는 여전히 고대 버전의 bash를 사용합니다. 다른 곳에 최신 bash를 설치했을 수도 있지만 내가 아는 한 shebang에 사용된 /bin/bash는 5.2가 아니라 3.2.x입니다.
를 참조하면 해당 특정 문제가 해결되지만 여기서 반복 결과는 $(find...)
확실히 잘못된 접근 방식입니다.find
이유와 올바른 대안을 확인하세요찾기 결과를 반복하는 것이 왜 나쁜 습관입니까?
즉, bash
루프( 에서도 사용할 수 있음 zsh
)를 사용해야 하는 경우:
while IFS= read -rd '' -u3 file; do
something with "$file"
done 3< <(find . -type f -print0 2> /dev/null)
(프로세스 교체,,,,, -r
ksh에서 복사된 모든 것은 -u
2.05b 이전 -d
또는 2.05b와 동일한 버전에 도입되었으므로 <<<
macos에서 사용할 수 있어야 합니다 /bin/bash
)
macos에는 zsh가 사전 설치되어 있으므로 zsh로 전환하여 다음을 작성할 수도 있습니다.
for file (**/*(ND.)) something with $file
또한보십시오: