Devin.KR
로그인

리눅스 rm 명령어 사용법 - 안전하게 파일 삭제하는 법과 rm -rf 사고 예방

개발자 조회 2

이 명령어를 언제 쓰는가

rm은 파일과 디렉토리를 지운다. 디스크가 찼을 때 오래된 로그를 정리하거나, 배포 실패한 릴리스 디렉토리를 걷어내거나, 임시 파일을 치울 때 쓴다.

리눅스의 rm에는 휴지통이 없다. 지운 순간 디렉토리 엔트리가 사라지고, 그 파일을 열고 있는 프로세스가 하나도 없으면 블록이 즉시 회수된다. 그래서 rm은 "어떻게 쓰는가"보다 "어떻게 안전하게 쓰는가"가 전부인 명령이다. 아래 함정 섹션이 이 글의 본론이다.

기본 형식

rm [옵션] 파일 [파일 ...]

기본적으로 일반 파일만 지운다. 디렉토리는 -r(재귀)이 있어야 지워지고, 빈 디렉토리는 -d 또는 rmdir로 지울 수 있다.

자주 쓰는 옵션

옵션의미예시
-r디렉토리와 그 안의 내용을 재귀적으로 삭제rm -r old_release
-f없는 파일을 무시하고, 확인을 묻지 않는다rm -f /tmp/app.pid
-i파일마다 삭제 여부를 묻는다rm -i *.log
-I3개를 넘거나 재귀 삭제일 때 한 번만 묻는다rm -I *.log
-v지운 파일을 출력한다(작업 로그 남기기)rm -rv build/
-d빈 디렉토리를 지운다(내용이 있으면 실패)rm -d empty_dir
--one-file-system다른 마운트로 넘어가지 않는다(GNU)rm -rf --one-file-system /mnt/tmp
--여기부터는 옵션이 아니라 파일명rm -- -tmp.log

실전 예제

1) 30일 지난 로그만 지운다rm *.log로 싹 지우는 대신 조건을 붙인다. 실무에서 가장 자주 쓰는 형태다.

find /var/log/myapp -name '*.log' -mtime +30 -print   # 먼저 목록만 확인
find /var/log/myapp -name '*.log' -mtime +30 -delete  # 확인 후 삭제

2) 지우기 전에 반드시 목록을 눈으로 본다 — 같은 패턴을 ls로 먼저 돌려보는 습관이 사고를 막는다.

ls -la /opt/app/releases/20260801*
rm -rf /opt/app/releases/20260801*

3) 대시로 시작하는 파일 지우기rm -tmp.log는 옵션으로 해석돼 실패한다.

rm -- -tmp.log
rm ./-tmp.log      # 이렇게 해도 된다

4) 파일 수가 너무 많아 rm이 실패할 때 — 세션 파일이 수십만 개 쌓인 디렉토리에서 rm *는 인자 길이 제한에 걸린다.

find /var/lib/php/sessions -type f -name 'sess_*' -print0 | xargs -0 -r rm -f

5) 지웠는데 디스크가 안 비었을 때 — 프로세스가 파일을 열고 있으면 용량이 그대로다. 실제 서비스 중 로그를 지웠을 때 흔히 겪는다.

lsof +L1 | head            # 링크 수 0인데 열려 있는 파일 확인
systemctl restart myapp    # 또는 해당 프로세스 재시작

함정과 주의점

변수를 쓸 때 값이 비면 경로가 루트가 된다. 실제 대형 사고의 단골 패턴이다.

# 위험: DIR이 비어 있으면 rm -rf /* 와 같아진다
rm -rf "$DIR"/*

# 안전: 값이 비었는지 먼저 검사한다
[ -n "$DIR" ] && [ -d "$DIR" ] && rm -rf "${DIR:?DIR is empty}"/*

${DIR:?}는 변수가 비었으면 셸이 에러를 내고 명령을 실행하지 않는다. 삭제 스크립트에는 이 형태를 쓴다.

경로 사이의 공백 하나가 디렉토리 두 개를 지운다. rm -rf /opt/app /tmp처럼 오타로 공백이 들어가면 의도하지 않은 대상까지 삭제된다. 특히 rm -rf / opt/app은 루트를 겨냥한다. GNU rm--preserve-root가 기본이라 인자가 정확히 /인 경우는 거부하지만, /*/opt는 그대로 지운다. 방어 장치를 믿지 말고 엔터 전에 한 번 읽는다.

상대 경로로 rm -rf를 치지 마라. 스크립트가 cd에 실패하면 엉뚱한 디렉토리에서 rm -rf ./data가 돈다. 삭제 대상은 절대 경로로 쓰거나, cd /opt/app || exit 1처럼 이동 실패를 반드시 잡는다.

-f는 안전장치를 끄는 옵션이다. 확인 프롬프트와 에러를 모두 없애기 때문에, 습관적으로 붙이면 잘못된 대상도 조용히 사라진다. 대화형 셸에서는 -I를 붙이는 편이 낫고, -f는 "없어도 에러 내면 안 되는" 스크립트 상황에만 쓴다.

alias rm='rm -i'에 의존하지 마라. 내 계정에서만 동작하고 root나 다른 서버, cron에서는 없다. 그리고 alias에 익숙해지면 프롬프트에 무심코 y를 누르는 습관이 생긴다. 안전은 alias가 아니라 지우기 전 ls로 확인에서 나온다.

삭제된 파일은 되돌릴 수 없다. ext4·XFS에서 사실상 복구 수단이 없다고 보는 편이 맞다. 중요한 데이터라면 지우는 대신 mv/tmp/trash 같은 곳에 옮겨 두고, 며칠 뒤 지우는 절차를 쓴다.

함께 보면 좋은 명령어

  • find — 조건으로 대상을 고른 뒤 -deletexargs rm으로 넘긴다. 실무 삭제는 대부분 이 조합이다.
  • rmdir — 비어 있을 때만 지운다. 내용이 남아 있으면 실패하므로 안전한 정리에 쓴다.
  • lsof — 지웠는데 용량이 안 줄 때, 파일을 붙잡고 있는 프로세스를 찾는다.