rsync: ví dụ đồng bộ file và sao lưu trên Linux
rsync sao chép và đồng bộ file cục bộ cũng như qua SSH, chỉ truyền phần đã thay đổi. Lệnh cơ bản là rsync -avz nguồn/ user@host:/đường-dẫn/: -a giữ quyền và thời gian, -v hiển thị file, -z nén dữ liệu; --delete làm đích thành bản sao chính xác của nguồn, còn -n cho phép kiểm tra kết quả trước mà không thay đổi gì.
rsync là công cụ tiêu chuẩn trên Linux để sao chép và đồng bộ file: cục bộ, giữa các ổ đĩa và giữa các máy chủ qua SSH. Điểm khác biệt chính với cp và scp là rsync chỉ truyền phần đã thay đổi, nên đồng bộ lại một thư mục lớn chỉ mất vài giây. Dưới đây là các ví dụ rsync cho những việc thường gặp: đưa dự án lên máy chủ, tạo bản sao gương của thư mục, loại trừ file, sao lưu bằng ảnh chụp và chạy theo lịch.
Cú pháp và các tùy chọn quan trọng nhất
Dạng lệnh tổng quát:
rsync [tùy-chọn] NGUỒN... ĐÍCH
Nguồn và đích có thể là đường dẫn cục bộ hoặc đường dẫn từ xa dạng user@host:/đường-dẫn. Một phía bắt buộc phải là máy cục bộ: rsync không sao chép trực tiếp giữa hai máy từ xa.
| Tùy chọn | Chức năng |
|---|---|
-a | chế độ lưu trữ: đệ quy, giữ quyền, chủ sở hữu, nhóm, thời gian sửa đổi và liên kết mềm (tương đương -rlptgoD) |
-v | hiển thị danh sách file được truyền |
-z | nén dữ liệu khi truyền qua mạng |
-h | hiển thị kích thước dễ đọc (K, M, G) |
-P | tương đương --partial --progress: hiển thị tiến trình và tiếp tục file bị ngắt |
-n, --dry-run | chạy thử: hiển thị những gì sẽ làm, không thay đổi gì |
--delete | xóa ở đích các file không có ở nguồn |
--exclude | không sao chép file theo mẫu |
-e | chỉ định shell từ xa, ví dụ -e "ssh -p 2222" |
-H, -A, -X | giữ liên kết cứng, ACL và thuộc tính mở rộng (không nằm trong -a) |
Trong thực tế, rsync -avh cục bộ và rsync -avzh qua mạng đáp ứng được phần lớn các trường hợp.
Dấu gạch chéo ở cuối đường dẫn: bẫy chính
Lỗi phổ biến nhất của người mới bắt đầu liên quan đến dấu / ở cuối nguồn. Nó quyết định sẽ sao chép chính thư mục hay chỉ nội dung bên trong.
# Sao chép THƯ MỤC project vào trong /backup → kết quả là /backup/project/...
rsync -av project /backup/
# Sao chép NỘI DUNG của project vào /backup → các file nằm trực tiếp trong /backup/
rsync -av project/ /backup/
Cách nhớ đơn giản: dấu / ở cuối nguồn nghĩa là "nội dung của thư mục này". Ở đích, dấu / không có vai trò gì. Nếu còn phân vân, thêm -n và xem rsync định tạo những đường dẫn nào.
Sao chép cục bộ
Sao chép một thư mục sang ổ USB, kèm hiển thị tiến trình:
rsync -avhP ~/photos/ /mnt/usb/photos/
Chạy lại đúng lệnh đó sẽ không sao chép lại mọi thứ: rsync so sánh kích thước và thời gian sửa đổi của file, rồi chỉ truyền file mới và file đã thay đổi. Phần kết quả cuối cho biết thực tế đã truyền bao nhiêu dữ liệu:
sending incremental file list
2026/10/IMG_2041.jpg
4.12M 100% 38.40MB/s 0:00:00 (xfr#1, to-chk=0/1534)
sent 4.13M bytes received 9.25K bytes 2.76M bytes/sec
total size is 6.82G speedup is 1,648.21
Giá trị speedup cho biết dữ liệu được truyền ít hơn bao nhiêu lần so với việc sao chép toàn bộ.
rsync qua SSH: sao chép lên máy chủ và ngược lại
Với đường dẫn từ xa, rsync mặc định dùng SSH, nên không cần cấu hình thêm — chỉ cần đăng nhập bằng ssh thông thường. Dùng khóa SSH là tiện nhất: không phải nhập mật khẩu và có thể đưa lệnh vào cron.
# Đưa trang web lên máy chủ
rsync -avz ./site/ deploy@203.0.113.10:/var/www/site/
# Tải nhật ký từ máy chủ về máy mình
rsync -avz deploy@203.0.113.10:/var/log/nginx/ ./nginx-logs/
# SSH dùng cổng khác và khóa riêng
rsync -avz -e "ssh -p 2222 -i ~/.ssh/deploy_key" ./site/ deploy@203.0.113.10:/var/www/site/
rsync phải được cài trên cả hai máy, vì phía từ xa được khởi chạy qua SSH. Nếu chưa có, bạn sẽ thấy rsync: command not found — hãy cài gói (sudo apt install rsync hoặc sudo dnf install rsync).
Nếu máy chủ đã được khai báo trong ~/.ssh/config với một bí danh, rsync hiểu bí danh đó: rsync -avz ./site/ prod:/var/www/site/.
Cần quyền root trên máy chủ
Khi các file ở đích thuộc về root còn bạn đăng nhập bằng người dùng thường, có thể chạy rsync phía từ xa qua sudo:
rsync -avz --rsync-path="sudo rsync" ./conf/ admin@server:/etc/myapp/
Để cách này hoạt động, trên máy chủ phải cấu hình sudo cho rsync không cần mật khẩu (quy tắc trong sudoers), nếu không lệnh sẽ treo chờ nhập liệu.
Bản sao gương của thư mục: --delete
Mặc định rsync chỉ thêm và cập nhật file, không xóa gì. Để đích trở thành bản sao chính xác của nguồn, cần --delete:
rsync -avh --delete ~/projects/ /mnt/backup/projects/
Đây là tùy chọn mạnh và nguy hiểm. Một đường dẫn sai (ví dụ nguồn rỗng hoặc quên dấu /) có thể xóa dữ liệu ở đích. Vì vậy quy tắc là: mọi lệnh có --delete phải chạy thử trước với -n.
$ rsync -avhn --delete ~/projects/ /mnt/backup/projects/
sending incremental file list
deleting old-app/README.md
deleting old-app/
app/main.py
sent 1.20K bytes received 64 bytes 2.53K bytes/sec
total size is 18.4M speedup is 14,554.39 (DRY RUN)
Các dòng deleting cho biết sẽ xóa những gì. Khi đã chắc chắn mọi thứ đúng, chạy lại không có -n.
Một số biến thể hữu ích: --delete-after xóa file sau khi truyền xong (đích giữ đầy đủ lâu hơn), còn --backup --backup-dir=/mnt/backup/deleted-$(date +%F) không xóa mà chuyển các file bị xóa hoặc bị ghi đè sang một thư mục riêng.
Loại trừ file: --exclude và --include
Loại trừ file tạm, thư viện phụ thuộc và bí mật là việc thường làm khi triển khai và sao lưu.
# Nhiều mẫu cùng lúc
rsync -avz --exclude='.git/' --exclude='node_modules/' --exclude='*.log' ./app/ server:/srv/app/
# Đọc các mẫu từ tệp
rsync -avz --exclude-from='.rsyncignore' ./app/ server:/srv/app/
Tệp .rsyncignore là danh sách đơn giản các mẫu, mỗi dòng một mẫu:
.git/
node_modules/
*.log
.env
tmp/
Cách các mẫu hoạt động:
- Mẫu không bắt đầu bằng dấu
/(*.log) khớp ở mọi độ sâu. - Mẫu bắt đầu bằng
/(/tmp/) gắn với gốc của lần truyền — chỉ loại trừ thư mụctmpở trên cùng. - Dấu
/ở cuối (cache/) nghĩa là "chỉ thư mục". - Các quy tắc được kiểm tra theo thứ tự, mẫu khớp đầu tiên được áp dụng.
Từ quy tắc cuối cùng có một mẹo "chỉ sao chép những gì cần": cho phép trước, rồi loại trừ phần còn lại.
# Chỉ sao chép các file .conf, giữ nguyên cấu trúc thư mục
rsync -av --include='*/' --include='*.conf' --exclude='*' /etc/ ./etc-confs/
Ở đây --include='*/' cần thiết để rsync đi vào mọi thư mục con. Thêm --prune-empty-dirs (-m) để không tạo các thư mục rỗng.
Sao lưu bằng rsync
Bản sao hằng ngày đơn giản
Sao lưu tối thiểu thư mục home sang ổ thứ hai:
rsync -aH --delete --exclude='.cache/' /home/alice/ /mnt/backup/alice/
Hạn chế của cách này là chỉ giữ một phiên bản. Nếu file bị hỏng và bản sao đã đồng bộ kịp thời, bản cũ sẽ mất.
Ảnh chụp tăng dần với --link-dest
Tùy chọn --link-dest giải quyết vấn đề này gần như miễn phí về dung lượng. File không thay đổi không được sao chép lại mà được tạo thành liên kết cứng tới file ở ảnh chụp trước. Mỗi ảnh chụp trông như một bản sao đầy đủ, nhưng chỉ chiếm dung lượng của phần thay đổi.
#!/bin/bash
set -euo pipefail
SRC="/home/alice/"
DEST="/mnt/backup/snapshots"
TODAY="$(date +%F)"
mkdir -p "$DEST"
rsync -aH --delete \
--exclude='.cache/' \
--link-dest="$DEST/latest" \
"$SRC" "$DEST/$TODAY"
ln -sfn "$DEST/$TODAY" "$DEST/latest"
Lần chạy đầu tiên chưa có thư mục latest — rsync sẽ đưa ra cảnh báo và tạo bản sao đầy đủ, điều này là bình thường. Ảnh chụp cũ được xóa bằng rm -rf thông thường: các file mà ảnh chụp khác vẫn liên kết tới sẽ không mất.
Xóa ảnh chụp cũ hơn 30 ngày có thể làm như sau:
find /mnt/backup/snapshots -maxdepth 1 -type d -name '20*' -mtime +30 -exec rm -rf {} +
Sao lưu máy chủ sang máy khác
Nên chọn chiều "từ máy sao lưu về máy làm việc": máy sao lưu tự kéo dữ liệu về, còn máy chủ làm việc không có quyền truy cập vào các bản sao. Nếu máy chủ bị xâm nhập, các bản sao vẫn an toàn.
rsync -azH --delete -e "ssh -i /root/.ssh/backup_key" \
backup@web01:/var/www/ /srv/backups/web01/www/
Lưu ý không được sao chép cơ sở dữ liệu theo cách này: các file của hệ quản trị CSDL đang chạy không nhất quán tại thời điểm sao chép. Hãy xuất bản dump trước (mysqldump, pg_dump), rồi để rsync chuyển file dump đã hoàn chỉnh.
Chạy theo lịch bằng cron
Đưa script sao lưu vào cron bằng lệnh crontab -e:
# Mỗi ngày lúc 03:15, ghi đầu ra vào nhật ký
15 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
Những điều cần kiểm tra để bản sao chạy đúng từ cron:
- Script dùng đường dẫn tuyệt đối: cron có PATH tối thiểu và thư mục hiện tại khác.
- Khóa SSH không có mật khẩu, và máy chủ đã có trong
known_hosts— nếu không, rsync sẽ treo chờ xác nhận khóa máy chủ. - Script kiểm tra mã thoát: rsync trả về 0 khi thành công, 23 nếu một phần file không được truyền, 24 nếu file biến mất trong lúc sao chép.
- Để tránh hai bản sao chạy đồng thời, dùng
flock:flock -n /tmp/backup.lock /usr/local/bin/backup.sh.
Thay vì cron, có thể dùng systemd timer — nó ghi đầu ra vào nhật ký và xem kết quả tiện qua journalctl.
Tùy chọn hữu ích cho các lần truyền lớn
| Việc cần làm | Tùy chọn |
|---|---|
| Giới hạn tốc độ để không làm nghẽn đường truyền | --bwlimit=5M |
| Tiếp tục file lớn sau khi bị ngắt | -P (hoặc --partial) |
| Hiển thị tiến trình chung thay vì danh sách file | --info=progress2 |
| So sánh theo nội dung thay vì thời gian | -c (--checksum), chậm hơn |
| Không ghi đè file ở đích đang mới hơn | -u (--update) |
| Không ghi đè file đã tồn tại | --ignore-existing |
| Xóa file nguồn sau khi truyền (di chuyển) | --remove-source-files |
| Thống kê chi tiết ở cuối | --stats |
Lỗi thường gặp và cách khắc phục
Permission deniedkhi ghi — người dùng không có quyền trên thư mục đích. Kiểm tra chủ sở hữu thư mục hoặc dùng--rsync-path="sudo rsync".- File được sao chép lại mỗi lần — thời gian sửa đổi không được giữ. Hãy đảm bảo có
-ahoặc-t; trên FAT/exFAT thêm--modify-window=2, vì các hệ thống này lưu thời gian với độ chính xác hai giây. - Lỗi
chownhoặcchgrpkhi sao chép sang USB hoặc thư mục mạng — hệ thống tập tin không hỗ trợ chủ sở hữu. Thay-abằng-rlt. - Xuất hiện thư mục lồng
/backup/project/project— nhầm dấu/ở cuối nguồn. connection unexpectedly closed— lỗi SSH hoặc rsync chưa được cài ở phía từ xa. Kiểm tra đăng nhập bằngsshthông thường và việc córsynctrên máy chủ.
Tóm lại
Để dùng hằng ngày, chỉ cần nhớ vài lệnh: rsync -avz nguồn/ host:/đích/ để sao chép qua SSH, --delete cùng với lần chạy thử -n cho bản gương, --exclude để bỏ phần thừa, và --link-dest cho sao lưu dạng ảnh chụp. Hãy để ý dấu / ở cuối nguồn — và rsync sẽ trở thành cách đáng tin cậy nhất để chuyển file giữa các máy. Đồng bộ và sao lưu được thực hành cụ thể trong khóa học Linux.
Câu hỏi thường gặp
rsync có ưu điểm gì so với scp?
scp luôn sao chép toàn bộ file, còn rsync chỉ truyền phần thay đổi, biết tiếp tục truyền dở dang, xóa file thừa ở đích và loại trừ file theo mẫu. Với việc sao chép một file một lần thì hai lệnh gần như giống nhau, còn với đồng bộ định kỳ rsync nhanh hơn rất nhiều.
Có dùng được rsync trên Windows không?
Có, thông qua WSL — nơi rsync cài và hoạt động như trên Linux thông thường — hoặc qua Cygwin. Để đồng bộ file giữa máy Windows và máy chủ Linux, WSL là lựa chọn tiện nhất.
rsync có mã hóa dữ liệu truyền đi không?
Bản thân rsync không mã hóa, nhưng khi chạy qua SSH thì toàn bộ lưu lượng đi qua kết nối SSH đã được mã hóa. Không mã hóa chỉ xảy ra khi làm việc với daemon rsync qua địa chỉ dạng rsync://.
Làm sao kiểm tra bản sao có khớp với bản gốc không?
Chạy rsync -avnc nguồn/ đích/ — tùy chọn -c so sánh theo checksum, còn -n không thay đổi gì. Nếu danh sách file trống, hai bản sao giống hệt nhau.
Điều gì xảy ra nếu dừng rsync giữa chừng?
Các file đã truyền xong vẫn còn, file đang truyền dở mặc định bị xóa. Chạy lại đúng lệnh đó sẽ tiếp tục từ chỗ dừng; với tùy chọn -P, phần file dở dang cũng được giữ lại.
Chủ đề này được giảng chi tiết kèm thực hành trong khóa học “Linux: с нуля до уверенного администрирования”.
Đến khóa học