Devin.KR
로그인

리눅스 rsync 명령어 사용법 - 동기화와 백업 옵션 정리, 실전 예제

개발자 조회 2

이 명령어를 언제 쓰는가

배포할 때마다 수천 개 파일을 통째로 올리는 대신 바뀐 것만 보내고 싶을 때, 새벽에 끊긴 백업을 이어서 돌리고 싶을 때, 원본에서 지운 파일을 사본에서도 지워 두 곳을 정확히 같게 맞추고 싶을 때 rsync를 쓴다.

핵심은 차등 전송이다. rsync 는 양쪽 파일을 비교해 달라진 부분만 보내므로, 두 번째 실행부터는 전송량이 극적으로 줄어든다. 그래서 매일 도는 백업 스크립트, 배포 스크립트, 서버 이전 작업의 기본 도구가 된다. 대신 경로 끝 슬래시 하나로 결과가 완전히 달라지는 위험한 도구이기도 하다.

기본 형식

rsync [옵션] 원본 대상
  • 원본 — 끝에 / 를 붙이면 디렉터리 안의 내용을, 붙이지 않으면 디렉터리 자체를 보낸다. 이 규칙이 rsync 사용의 전부라고 해도 과장이 아니다.
  • 대상 — 로컬 경로 또는 사용자@호스트:경로. 대상의 슬래시는 동작에 영향을 주지 않는다.
  • 원본과 대상 중 원격은 한쪽만 가능하다. 원격끼리 직접 동기화는 되지 않는다.

자주 쓰는 옵션

옵션의미예시
-a보관 모드. 재귀 + 권한·시각·심볼릭 링크 보존rsync -a src/ dst/
-v / -h전송 파일 표시 / 크기를 읽기 쉽게rsync -avh src/ dst/
-z전송 중 압축. 원격 전송에서만 의미 있다rsync -avz src/ host:/dst/
-P--partial --progress. 진행률 + 중단 시 이어받기rsync -avP big/ host:/dst/
-n실제로 하지 않고 결과만 보여준다(dry-run)rsync -avn --delete src/ dst/
--delete원본에 없는 파일을 대상에서 삭제rsync -av --delete src/ dst/
--exclude '패턴'제외할 경로. 여러 번 쓸 수 있다--exclude '.git' --exclude 'node_modules'
-e '명령'원격 셸 지정. 포트가 다를 때 쓴다-e 'ssh -p 22022'
--bwlimit=KB/s대역폭 제한. 운영 시간대 전송에 필수--bwlimit=5000
--link-dest=경로변경 없는 파일은 하드링크로 연결(증분 백업)--link-dest=/backup/2026-08-24
--chown=user:group대상 소유자를 지정(rsync 3.1 이상)--chown=www-data:www-data

실전 예제

1. 빌드 산출물을 운영 서버에 배포한다. 바뀐 파일만 올라가고, 삭제된 파일은 서버에서도 사라져 정확히 같은 상태가 된다.

rsync -avz --delete -e 'ssh -p 22022' \
  --exclude '.git' --exclude '*.map' \
  ./dist/ deploy@10.0.1.20:/var/www/app/
sending incremental file list
index.html
deleting assets/main.9ab73e.js
assets/main.4f2c1a.js
assets/main.4f2c1a.css

sent 214,882 bytes  received 1,204 bytes  144,057.33 bytes/sec
total size is 3,118,442  speedup is 14.43

2. 실행 전에 반드시 먼저 돌려본다. --delete 가 들어간 명령은 예외 없이 이 단계를 거친다. deleting 으로 시작하는 줄이 예상과 같은지 확인한 뒤에 -n 을 빼고 다시 친다.

rsync -avzn --delete -e 'ssh -p 22022' ./dist/ deploy@10.0.1.20:/var/www/app/

3. 끊긴 대용량 전송을 이어서 한다. DB 덤프 같은 수십 GB 파일에 쓴다. 같은 명령을 다시 치면 중단 지점부터 재개된다.

rsync -avP --bwlimit=5000 dump-20260825.sql.gz deploy@10.0.1.30:/backup/

--bwlimit=5000 은 초당 약 5MB 다. 이 제한이 없으면 백업 전송이 회선을 다 먹어 서비스 응답이 느려진다.

4. 하드링크로 증분 백업을 만든다. 날짜별 디렉터리가 각각 전체 스냅샷처럼 보이지만, 바뀌지 않은 파일은 디스크를 추가로 쓰지 않는다.

TODAY=$(date +%F)
YESTERDAY=$(date -d yesterday +%F)
rsync -a --delete \
  --link-dest="/backup/$YESTERDAY" \
  /var/www/app/ "/backup/$TODAY/"

5. 제외 목록을 파일로 관리한다. 제외 규칙이 다섯 개를 넘으면 명령줄이 읽기 어려워진다.

cat > /etc/rsync-exclude.txt <<'EOF'
.git/
node_modules/
*.log
tmp/
EOF

rsync -avz --exclude-from=/etc/rsync-exclude.txt ./ host:/srv/app/

함정과 주의점

원본 경로 끝 슬래시가 결과를 뒤집는다. rsync 사고의 대부분이 여기서 나온다.

rsync -av /src/app/  /dst/    # /dst/index.html      (내용물이 들어간다)
rsync -av /src/app   /dst/    # /dst/app/index.html  (디렉터리째 들어간다)

두 번째 형태를 쓰고 나서 --delete 를 붙이면, 대상에 원래 있던 파일이 전부 지워지고 한 단계 더 깊은 곳에 복사본이 생긴다. 웹 루트를 통째로 날리는 전형적인 사고다. 명령을 짤 때 원본 슬래시를 먼저 확정하고 시작한다.

--delete 는 dry-run 없이 실행하지 않는다. 대상 경로를 한 글자 잘못 적으면 그 디렉터리의 내용이 통째로 사라진다. 취소도 휴지통도 없다. -n 을 붙여 확인하는 30초가 복구 작업 하루를 막는다.

-a 로 소유자·그룹을 보존하려면 root 여야 한다. 일반 계정으로 실행하면 소유자만 조용히 실행 계정으로 바뀐 채 성공한다. 웹 파일이 전부 deploy 소유가 되어 nginx 가 403 을 뱉는 식으로 뒤늦게 드러난다. 대상 소유자가 중요하면 --chown 을 명시하거나 root 로 돌린다.

--exclude 한 파일은 --delete 로도 지워지지 않는다. 대상에 남아 있는 옛 파일이 제외 패턴에 걸리면 영원히 남는다. 정말 완전한 미러가 필요하면 --delete-excluded 를 쓰되, 이 옵션은 위험도가 한 단계 더 높으니 dry-run 을 두 번 돌린다.

함께 보면 좋은 명령어

  • ssh~/.ssh/config 에 별칭과 포트를 정의해 두면 -e 'ssh -p ...' 를 매번 쓰지 않아도 된다.
  • scp — 파일 한두 개를 한 번만 보낼 때는 rsync 보다 손이 덜 간다.
  • find — 전송 대상을 조건으로 추려낸 뒤 --files-from 으로 넘길 때 함께 쓴다.