`rm -rf`는 원자가 아닙니까?


11

혼란스러운 오류가 발생했습니다.

rm: cannot remove `xxx/app/cache/prod': Directory not empty

다음 명령으로 발생한 것입니다.

rm -rf $cache_dir/*

어디로 $cache_dir정의xxx/app/cache

그래서 나는 그것을 본다 : dir에서 rm모든 것을 cache/prod제거한 다음 cache/prod디렉토리 를 제거하기 직전에 -다른 프로그램이 그 안에 파일 / 디렉토리를 생성하여 rm실패를 일으켰다 .

내 가정이 맞습니까?


7
당신의 가정은 정확합니다- rm -r원자가 아닙니다. 를 rm -rf실행 하는 동안 디렉토리에 더 이상 파일이 작성되지 않도록 하려면 먼저 이름을 바꾼 다음 이름을 바꾼 디렉토리를 제거하십시오.
Johnny

@Johnny : 그래, 내가 실제로 구현 한 것입니다 :-)
zerkms

비록 그것조차 완전히 안전하지는 않습니다. 앱이 현재 해당 디렉토리에서 작동하지 않는 경우 이동과 함께 정상적으로 작동합니다.
Patrick

rm -rf스레드 안전 과는 아무런 관련이 없습니다 . 동일한 디렉토리에서 여러 번 동시에 실행하면 디렉토리가 삭제됩니다. 이것은 rm -r원자 적이 지 않은 것입니다.
질 'SO-정지 존재 악마'

@Gilles : "여러 코드가 동시에 여러 스레드에 의해 안전한 실행을 보장하는 방식으로 공유 데이터 구조를 조작하는 경우 코드가 스레드로부터 안전합니다". 따라서 "스레드"를 rm호출 로 가정하면 스레드 안전성에 대해 말할 수 있습니다. 그러나 어쨌든, 그것은 아무것도 바뀌지 않습니다
zerkms

답변:


7

주어진 오류 메시지는 "디렉토리가 비어 있지 않음"( ENOTEMPTY)인데,이 가정이 정확하다고 들리면 프로그램이 디렉토리 rm를 제거하려고 시도하기 직전에 해당 디렉토리에 파일을 생성 한 경합 조건이므로 ENOTEMPTY기본에서 예상되는 오류가 발생합니다 rmdir(2).

참고 : 안전을 위해 디렉토리를 새 이름으로 이동 / 이름 변경 한 다음이 디렉토리 삭제를 실행할 수 있습니다.


2
이 대답은 잘못되었습니다. 파일을 사용중인 경우에도 디렉토리 항목을 제거한 다음 디렉토리를 삭제할 수 있습니다. 간단한 테스트는 mkdir x; cat > x/a &; tail -f x/a &; rm -r x파일이 읽기 또는 쓰기 용으로 열려 있는지 여부에 관계없이 파일이 사용 중일 때도 디렉토리를 제거 할 수 있음 을 보여줍니다.
wingedsubmariner

1
예, 파일은 여전히 ​​존재하지만 디렉토리 삭제가 성공하지 못한 이유와는 관련이 없습니다. 귀하의 답변에있는이 진술은 구체적으로 거짓입니다 : "시스템은 파일이있는 파일을 가지고있는 디렉토리는 읽기 / 쓰기 모드로 열립니다". 귀하의 답변에 좋은 것들이 있습니다, 그것은 단지 질문에 관한 것이 아닙니다 :)
wingedsubmariner

1
또한 파일 디스크립터를 파일과 혼동하지 않도록주의하십시오. 파일 디스크립터는 절대 삭제되지 않고 닫힙니다.
wingedsubmariner

1
첫 번째 단락도 약간의 작업이 필요할 수 있습니다. 파일이 아직 열려있을 때 파일 삭제가 발생하지 않는 것은 맞습니다. 파일이 해당 디렉토리에서 연결 해제되면 디렉토리가 삭제되지 않도록하는 것입니다. 예, 이것은 UNIX가 처음에 보이는 것처럼 이상한 디렉토리에없는 파일이 존재할 수 있음을 의미합니다.
wingedsubmariner

1
OP의 직관이 정확하고 새 파일이 생성되었거나 권한 오류 인 경우 삭제가 실패하는 두 가지 이유 만 생각할 수 있습니다. rm권한 오류에 대해 불평하므로 제거 할 수 있다고 생각합니다. 그래도 답변을 게시 할만 큼 자신감이 없습니다.
wingedsubmariner
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.