온라인에서 for 루프의 예를 찾았습니다. 이제 내 코드에서 이것을 사용하고 싶지만 이 루프가 어떻게 작동하는지 잘 모르겠습니다.
for entry in "$search_dir"/*
do
echo "$entry"
done
이제 나는 묻고 싶다.
- 각 반복마다 search_dir을 조회하고 search_dir의 파일을 각 반복마다 항목 변수 하나의 파일에 복사합니까?
- 아니면 search_dir의 모든 내용에 대한 스냅샷을 찍은 다음 해당 스냅샷을 항목 변수에 저장합니까?
- 루프가 계속 작동하는 동안 누군가가 search_dir에 일부 파일을 삽입하면 출력이 변경됩니까?
답변1
쉘이 for
- 문에 도달하면 값을 확장 $search_dir
하고 파일 이름 글로빙을 수행하여 반복할 디렉터리 항목 목록을 생성합니다. 이는 한 번만 발생합니다. 루프의 내용이 $search_dir
사라지거나 새 파일/디렉터리가 디렉터리에 추가되면 해당 변경 사항이 적용되지 않습니다.
루프가 이름이 지정된 디렉터리 항목에서 작동하는 경우 해당 $entry
항목이 루프 내에 존재하는지 테스트할 수 있습니다. 특히 루프를 실행하는 데 오랜 시간이 걸리고 다음과 같은 이유로 지속적으로 변경되는 많은 수의 파일이 있는 경우에는 더욱 그렇습니다. 또 다른 :
for entry in "$search_dir"/*; do
if [ -e "$entry" ]; then
# operate on "$entry"
else
# handle the case that "$entry" went away
fi
done
Stéphane이 의견에서 올바르게 지적했듯이 이는 중복되는 테스트입니다.최대사례.
답변2
쉘은 루프 본문 실행을 시작하기 전에 루프할 값 목록을 완전히 결정합니다. 그건:
- 쉘은 변수의 값을 사용하여 경로를 작성합니다
search_dir
. - 쉘은 지정된 디렉토리에서 파일 이름 목록을 수집하여 일치하는 와일드카드 패턴 목록을 작성합니다.
- 쉘은 일치하는 목록의 각 요소에 대해 루프 본문을 차례로 실행합니다.
search_dir
루프가 실행되는 동안 변수의 값을 변경하고, 디렉터리의 내용을 변경할 수 있습니다. 이는 루프가 작동하는 파일에 영향을 주지 않습니다.
다른 파일을 반복하면서 파일을 삭제하는 경우 파일에 도달하면 해당 파일은 존재하지 않습니다. 루프에서 수행하는 작업에 따라 이는 중요할 수도 있고 중요하지 않을 수도 있습니다. 파일을 삭제할 수 있는 동시 프로세스가 있는 경우 처리 전에 파일이 존재하는지 테스트하는 것만으로는 문제가 실제로 해결되지 않는다는 점에 유의하세요.테스트 후 처리 시작 사이에 파일이 삭제될 수 있습니다..
파일이 두 번 처리되지 않도록 처리된 것으로 표시해야 하는 경우 이 스크립트는 파일이 처리된 후 파일을 다른 디렉터리로 이동해야 합니다. 동일한 파일 시스템의 다른 디렉터리로 파일을 이동하는 것은원자: 아직 완료되지 않았거나 이미 완료되었으며 중간 상태가 없습니다. 그런데 또 만약에다른프로세스(아마도 스크립트의 다른 인스턴스)가 파일을 이동하면 루프가 실행되는 동안 이동된 파일에 루프가 충돌하는 경우가 있습니다.
새 파일이 생성될 때 이를 처리하려면 다시 반복해야 합니다. 분명히 루프 실행 중이나 모든 이전 파일이 처리된 후에 파일이 생성될 수 있으므로 스크립트를 실행하는 데 시간이 오래 걸립니다. 디렉터리에 파일이 생성될 때까지 기다릴 수 있는 도구가 있습니다. Linux에서 기본 기능은 다음과 같습니다.inotify;파일이 생성될 때 파일을 처리해야 하는 경우inotifywait
또는잉크론당신을 도와야합니다. inotify는 생성된(또는 트리거에 따라 수정되거나 액세스된) 파일만 알려준다는 점을 기억하세요.뒤쪽에Inotify 기반 명령 실행; 기존 파일도 처리해야 하지만 for entry in *; do …; done; inotifywait …
루프 실행 중에 또는 명령 inotifywait
실행 시에도 파일이 생성될 수 있기 때문에 그렇게 할 수는 없습니다.