Shell script에서 for문과 배열 사용 시 주의점

Reading time ~1 minute

NAS에서 Thumbs.db 파일을 제거하기 위해 셸에서 아래와 같은 명령을 실행했다. (곧바로 rm 명령을 실행하기는 위험하기 때문에 우선 파일 경로를 제대로 찾아내는지를 확인하기 위한 스크립트이다)

$ for f in `find . | grep Thumbs.db`; do echo "$f"; done

경로에 빈 칸이 있을 경우를 대비해서 따옴표로 감싸줬는데, 빈 칸이 전부 line break되어 나왔다.

예를 들어 /space in path/Thumbs.db와 같은 경로가 있을 경우

/space
in
path/Thumbs.db

이런 식으로 출력되는 것이다.

그런데 생각해보니 bash의 배열은 공백으로 구분되기 때문에 당연한 결과였다.

for f in `find . | grep Thumbs.db` 이 부분은 for f in /space in path/Thumbs.db나 마찬가지이고, 배열의 원소인 /space, in, path/Thumbs.db가 차례로 들어갔던 것이다.

그리고 저런 형태로 스크립트를 구성하면 find-grep의 결과가 출력될 때마다 do-done 사이의 명령이 실행되는 것이 아니라, find-grep이 전부 실행되고 난 다음 do-done 사이의 명령이 실행된다.

그동안 너무 빠른 시스템에서 적은 수의 파일만 다루다보니 차이를 잘 몰랐는데, 이런 경우는 find -name -exec를 사용하는 것이 낫다.

$ find . -name Thumbs.db -exec rm "{}" \;

kiwi campus

가족여행차 샌 프란시스코에 갔다가 오랜만에 버클리 교정을 구경하러 갔다.돌아다니다보니 Sather gate 근처의 분수대 주변에 이런 게 돌아다니고 있었다.처음엔 학생이 만든 장난감 정도로 생각했다. 폰에 외장(?)렌즈를 달아서 꽂아놨는데 이게 ...… Continue reading