다음 스크립트때때로나에게 같은 것을 줘can't remove a/b as it's not empty
ssh -T user@host <<EOF
cd somewhere
rm -rf a/b
EOF
하지만 서버에 로그인하여 실행한 rm -rf a/b
후에는 문제가 발생하지 않았습니다.
파일을 생성하는 다른 프로세스가 있습니다 a/b
. 이것이 관련이 있습니까?
어쨌든, "a/b"가 제거되었는지 확인하는 스크립트를 어떻게 만들 수 있나요?
답변1
a/b에 파일을 생성하는 다른 프로세스가 있습니까? 관련이 있습니까?
아마. 아마도 rm -rf
모든 파일을 먼저 삭제한 다음 모든 디렉토리를 삭제할 것입니다. 그 뒤에서 rmdir
디렉토리가 비어 있지 않으면 디렉토리를 삭제하기 위한 시스템 호출이 실패합니다. rm -rf
디렉토리가 비어 있는지 확인하는 경쟁 조건이 있을 수 있으며 , 그런 다음 다른 프로세스가 최종적으로 rm -rf
호출되지만 rmdir
다른 프로세스는 미리 파일을 생성합니다.
Faheem의 제안은 좋습니다. ls
오류 조건을 입력 하세요.
ssh -T user@host <<EOF
cd somewhere
rm -rf a/b || ( ls -a a/b && exit 1 )
EOF
답변2
rmdir(2)
디렉터리가 비어 있지 않으면 실패합니다. rm(1)
파일이 삭제될 때 다른 프로세스에서 파일을 생성하는 경우 파일 삭제 방법을 알지 못하므로 rm(1)
빈 디렉터리라고 생각되는 내용을 삭제하려고 하면 게시한 오류와 함께 실패합니다.
디렉토리에 파일이 동시에 생성되는 동안 디렉토리를 삭제하는 한 가지 방법은 이름을 바꾸는 것입니다.
mv a a~
rm -rf a~
a/b
파일을 생성한 프로세스가 경로를 통해 실행되지 않은 경우( open(2)
대신 ) openat(2)
작동하지 않을 수 있습니다 .
파일이 생성되는 프로세스는 a/b
디렉터리가 없으면 디렉터리를 다시 생성하거나, 디렉터리가 없으면 오류를 정상적으로 처리할 것이라고 가정합니다. 이미 다른 프로세스에서 디렉터리 삭제를 시도했으므로 이는 안전한 가정인 것 같습니다.
답변3
경쟁 조건이 매우 높은 경우 다음 명령은 사용되지 않는 파일을 제거한 다음 빈 디렉터리를 제거합니다.
find /somedir -type f -atime +3 -print0 | xargs -0 --no-run-if-empty rm -f; find /somedir -mindepth 1 -type d -empty -not -name "*.empty" -print0 | xargs -0 --no-run-if-empty -I{} mv {} {}.empty; sleep 30; find /somedir -type d -name '*.empty' -print0 | xargs -0 --no-run-if-empty rm -rf
또는 단계별로:
find /somedir -type f -atime +3 -print0 | xargs -0 --no-run-if-empty rm -f;
find /somedir -mindepth 1 -type d -empty -not -name "*.empty" -print0 | xargs -0 --no-run-if-empty -I{} mv {} {}.empty;
sleep 30;
find /somedir -type d -name '*.empty' -print0 | xargs -0 --no-run-if-empty rm -rf;
수면 30모든 프로세스가 삭제된 디렉터리에 대한 쓰기를 완료하는 데 필요합니다.
경고: 새 데이터가 손실될 수 있습니다(내 경우에는 캐싱이므로 상관하지 않습니다.)