
온라인에서 for 루프 예제를 하나 찾았습니다. 이제 내 코드에서 이를 사용하고 싶지만 이 루프가 어떻게 작동하는지 잘 모르겠습니다.
for entry in "$search_dir"/*
do
echo "$entry"
done
이제 나는 그것을 묻고 싶다.
- 각 반복에서 search_dir을 찾고 search_dir의 파일을 각 반복에서 항목 변수 하나의 파일에 복사합니까?
- 아니면 search_dir의 모든 내용에 대한 스냅샷을 찍은 다음 해당 스냅샷을 항목 변수에 저장합니까?
- 루프가 계속 작동하는 동안 누군가가 search_dir에 일부 파일을 삽입하면 출력에 변화가 있습니까?
답변1
쉘이 -statement에 도달하면 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
명령이 시작되는 동안에도 파일이 생성될 수 있기 때문에 그렇게 할 수는 없습니다.