"rm -rf a/b"가 "a/b가 비어 있지 않음"이라고 말하는 이유는 무엇입니까?

"rm -rf a/b"가 "a/b가 비어 있지 않음"이라고 말하는 이유는 무엇입니까?

다음 스크립트때때로나에게 같은 것을 줘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모든 프로세스가 삭제된 디렉터리에 대한 쓰기를 완료하는 데 필요합니다.

경고: 새 데이터가 손실될 수 있습니다(내 경우에는 캐싱이므로 상관하지 않습니다.)

관련 정보