수많은 디렉토리 한꺼번에 지우기

slomo의 이미지

하드디스크를 정리하느라 많이 지울 일이 생겼습니다. 파일을 지우는 것은

$ find . -type f -print0  | xargs -0 rm

으로 가능한데. 디렉토리는 어떻게 지우나요? 파일은 다 지우고 빈 디렉토리들만 남아있는데 디렉토리도 너무 많아서 rm -rf *로는 무리가 있는 듯 합니다.

익명 사용자의 이미지

$ find . -type d -exec rm -rf {} \;

slomo의 이미지

그건 어차피 rm -rf 라서 소용이 없는 것 같은데요.

====
No one asks you for change or directions.
-- Slo-Mo, J. Krokidas

Prentice의 이미지

rm -rf * 이거와는 달리 find -exec에서는 * 확장(?)을 셸이 하는 게 아니라서 빠를 거예요.

slomo의 이미지

디렉토리들이 수평적으로 그냥 개수만 많은 거면 말씀대로 될 것 같은데 계층적으로 복잡하게 많은 것이라서요.
find가 던져주는 첫번째 디렉토리에 대해서 rm -rf가 걸리고 다음 던져주는 디렉토리에 또 걸리고 그러는 것 아닌가요?
그 디렉토리 내부가 계층적으로 복잡하면 어차피 소용이 없지 않나요?

====
No one asks you for change or directions.
-- Slo-Mo, J. Krokidas

Prentice의 이미지

혹시 그렇지 않을까 생각했는데 역시 그러셨군요 ㅠㅠ

find -exec보다는 xargs가 빠르다는 것 같으니 제 답은 무시하셔도 될 것 같습니다. (아, 익명 답변은 제가 드린 답변이 아닙니다.)

익명 사용자의 이미지

계층적으로 많으면 상위디렉토리에서 rm -rf 하면 될것 같은데요
상황이 잘 이해가 안 가네요

find 조건에 -maxdepth -mindepth 넣고 rm -rf 하면 웬만하면 다 될듯

slomo의 이미지

예를 들어 현재 디렉토리 아래 있는 모든 것을 지우고 싶은데 디렉토리가 a, b, c 세개가 있다고 하죠.
find에서 rm -rf 하면 첫번째로 a 디렉토리가 넘겨지고 `rm -rf a`가 실행되겠죠.
그런데 a의 내부가 계층적으로 너무 복잡하여 `rm -rf a`가 작동이 안 되면 그 다음에는 아무 것도 안 되는거죠.
그래서 그냥 rm -rf *을 하나 find에서 rm -rf를 하나 별반 차이가 없는 상황이죠.

====
No one asks you for change or directions.
-- Slo-Mo, J. Krokidas

익명 사용자의 이미지

a가 아무리 복잡해도 rm -rf 가 안되지는 안을텐데요
시간이 걸릴뿐이지요

rm 자체에 limit이 있나요?

익명 사용자의 이미지

$ find . -type d -delete
-exec rm {} \;보다 -delete 옵션이 있네요.

$ ionice -n7 nice rm -rf dir_name
아니면 ionicenice를 써서 조금이라도 빨리...

살릴 데이터는 옮기고 파티션을 포맷하는 방법도 있지만
적용하기 어려운 여건일 수도 있겠군요.

superuser.com Q&A
serverfault.com Q&A
another serverfault.com Q&A
stackexchange.com Q&A
blog post
metafilter.com Q&A 서버 과부하 피하며 지우기

익명 사용자의 이미지

몇 가지 명령에 대해 간단하게 시간을 재봤습니다.
여러번 시행해봤는데 편차는 얼마 없었습니다만은,
디렉토리 1만 개를 만들고 바로 지우는 방법이라,
명령어들 모두 캐쉬의 영향을 많이 받았을겁니다.
*좋은 벤치마크는 아니지요. 그냥 참고로 보실 분만=3=3==3
ionicenice는 써도 결과에 별 차이가 없어서 생략합니다.
승자는...?

$ for d in {0..9}; do mkdir -p $d/{0..9}/{0..9}/{0..9}; done && time find . -depth -type d -exec rmdir {} \;
rmdir: failed to remove ‘.’: Invalid argument
 
real    0m5.993s
user    0m0.132s
sys     0m0.676s

$ for d in {0..9}; do mkdir -p $d/{0..9}/{0..9}/{0..9}; done && time rm -rf *
 
real    0m0.279s
user    0m0.026s
sys     0m0.246s

$ for d in {0..9}; do mkdir -p $d/{0..9}/{0..9}/{0..9}; done && time find . -type d -delete
 
real    0m0.324s
user    0m0.054s
sys     0m0.267s

$ for d in {0..9}; do mkdir -p $d/{0..9}/{0..9}/{0..9}; done && time find . -depth -type d -exec rm -r {} \;
rm: cannot remove directory: ‘.’
 
real    0m6.504s
user    0m0.153s
sys     0m0.669s

$ for d in {0..9}; do mkdir -p $d/{0..9}/{0..9}/{0..9}; done && time find . -type d -exec rm -rf {} \;
rm: cannot remove directory: ‘.’
find: `./7': No such file or directory
find: `./1': No such file or directory
find: `./6': No such file or directory
find: `./8': No such file or directory
find: `./0': No such file or directory
find: `./2': No such file or directory
find: `./9': No such file or directory
find: `./4': No such file or directory
find: `./5': No such file or directory
find: `./3': No such file or directory
 
real    0m0.303s
user    0m0.034s
sys     0m0.241s

rm -rf *가 가장 빠르네요. 그 다음이
find . -type d -exec rm -rf {} \;고, 그 다음이
find . -type d -delete네요.

나머지는 위 세 개 방법보다 많이 느리군요.
rm -rf *가 많이 최적화 되어서 linear하다고 합니다.
물론 I/O 때문에 시간이 많이 늘어나지만요.

아무래도 rm -rf *가 안된다면,
자료 백업하고 파티션 포맷이 가장 확실한 방법인 것 같습니다.

slomo의 이미지

그런데, 예를 들어, 2T 디스크 4개로 RAID0+1글 구성한 4T짜리 NAS에서라면 안 지울 자료만 백업하고 파티션 포맷한 후 다시 집어넣는 것은 배보다 배꼽이 커질 수도 있겠죠. 그래서 rm -rf *보다 느리더라도 할 수 있는 다른 방법을 찾는 거겠죠.

====
No one asks you for change or directions.
-- Slo-Mo, J. Krokidas

익명 사용자의 이미지

파일삭제
1. 파일 컨텐츠가 점유하고 있는 모든 데이타블럭을 찾아서 블럭자체는 그대로 두고 비트맵만 0 (미사용블럭표시)
2. 파일명이 기록된 디렉토리 데이타블럭을 찾아서 그 블럭 내용 내용중 파일명 관련 삭제

디렉토리삭제
최 하위부터 상위방향으로 모든 파일에 대해 블럭 비트맵 0 디렉토리 비트맵 0 ->현재 디렉토리는 상위 디렉토리에 이름만 등록되고 컨텐츠는 비어있는 공디렉토리,이 상태에서 상위 1단계 올라가서 같은 짓 반복...

파일은 데이타블록 컨텐츠가 유저데이타라는것과 디렉토리는 데이타블록 컨텐츠가 메타데이타라는 것의 차이만 있을 뿐 어떻게 빨리 삭제하느냐의 원론은 없음

파일시스템을 통하지 않고 최상위 디렉토리의 데이타블럭 4KB 비트맵을 0 로 해버리면 하위가 다 날아가지만 하위의 비트맵 1 데이타블럭은 디스크를 점유하고 있지만 파일시스템으로 액세스가 불가능하고 dd 따위로만 복구되는데....

이런식으로 하고 파일시스템 체크유틸로 데이타블록 비트맵을 0 로 해주는 방법이 있을것도 같습니다만....

익명 사용자의 이미지

그렇지 않겠지만 혹시나해서 말씀드리는건데
삭제하고자하는 최상위 디렉토리안에 애초에 파일/디렉토리명이 많았거나 이름이 지나치게 길어 4KB 를 초과할 경우 추가된 블럭도 비트맵 0 로 만들어야 하고 이러한 모든 작업은 파일시스템에서 지원하지 않는 메타데이타편집이라 위험합니다.

파일시스템에 따라 다르고 메타데이타가 복잡할 수 있지만 기본적으로
"어떤 데이타블럭 비트맵을 제로로 만드는 작업에 파일과 디렉토리의 차이는 없으며 그 원론적인 효율성도 논할 수 없다"
입니다

wwwroot7의 이미지

빈폴더 지우기
hp-unix

du -k /폴더명/폴더명 |awk '{ if ($1<10) print $2 }' |xargs rmdir

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.