Di chuyển tập tin và xóa thư mục với rsync?


17

Gần đây tôi cần xóa một số lượng lớn tệp (hơn 1 triệu) và tôi đọc được điều đó:

rsync -av --delete `mktemp -d`/ ~/source && rmdir ~/source

Là một trong những cách tối ưu nhất để làm điều đó và tôi có thể khẳng định rằng nó nhanh hơn rm -rf.

Tôi không phải là một chuyên gia về vấn đề này, nhưng theo hiểu biết của tôi, lý do cho hiệu suất rsync có gì đó để thực hiện theo cách liệt kê các tệp (LIFO thay vì FIFO tôi cho rằng). Bây giờ, vấn đề là, tôi cũng cần phải di chuyển một số lượng lớn các tệp một cách hiệu quả. Sau khi tìm kiếm một chút, tôi thấy điều này:

rsync -av --ignore-existing --remove-source-files ~/source ~/destination

Trong khi điều này xóa tất cả các tập tin di chuyển trong ~/source, các thư mục vẫn ở đó. Vì tôi có cấu trúc thư mục giống như "vòng tròn", số lượng files/directoriesrất gần với 1, vì vậy tôi buộc phải chạy lại lệnh đầu tiên để loại bỏ hoàn toàn thư mục:

rsync -av --ignore-existing --remove-source-files ~/source ~/destination && \
rsync -av --delete `mktemp -d`/ ~/source && rmdir ~/source

Một đường thẳng mvsẽ hoàn thành gần như ngay lập tức, nhưng ~/destinationthư mục của tôi có các tệp nên được giữ, vì vậy mvkhông phải là một tùy chọn. Tôi đã tìm thấy các tùy chọn --prune-empty-dirs--forcersync, nhưng dường như không hoạt động như tôi mong đợi:

--force                 force deletion of directories even if not empty
--prune-empty-dirs      prune empty directory chains from the file-list
--remove-source-files   sender removes synchronized files (non-dirs)

Có cách nào để bắt chước một động thái với rsync trong một lần không?


2
Nếu bạn không nhận được câu trả lời ở đây, hãy thử đăng lên danh sách rsync. Chúng rất hữu ích. list.samba.org/mailman/listinfo/rsync
Joe

Câu trả lời:


7

Tôi tìm thấy chủ đề này trên stackoverflow có tiêu đề: Xóa các thư mục với rsync Wap di chuyển? , đó là hỏi về cơ bản cùng một câu hỏi. Một trong những câu trả lời được đề xuất thực hiện rsynctrong 2 lệnh vì nó xuất hiện không có một lệnh nào có thể thực hiện việc di chuyển / loại bỏ các tệp và thư mục nguồn.

$ rsync -av --ignore-existing --remove-source-files source/ destination/ && \
  rsync -av --delete `mktemp -d`/ source/ && rmdir source/

Ngoài ra, bạn có thể làm điều đó bằng cách sử dụng lệnh này:

$ rsync -axvvES --remove-source-files source_directory /destination/ && \
  rm -rf source_directory

Không lý tưởng nhưng làm công việc.


Vâng, chính tôi là người đã trả lời câu hỏi đó (và cùng một "giải pháp" cũng nằm trong câu hỏi này). = P
Alix Axel

@AlixAxel - Ha, xin lỗi tôi thậm chí không nhận thấy bạn đã trả lời câu hỏi đó. Ồ tốt Tôi sẽ xóa câu trả lời này sau đó?
slm

3
Sử dụng rsyncđể cắt tỉa các thư mục không cảm thấy đúng và luôn có nguy hiểm rm -rf. Tôi muốn giới thiệu bước thứ 2 là:find source/ -d -type d -exec rmdir {} \;
zany 13/12/13

2
Tôi chỉ cảm thấy bắt buộc phải thêm, không bao giờ sử dụng -delete--remove-source-filestrong một lệnh rsync duy nhất (các ví dụ trên là tốt, điều này là tiếp tuyến). Nếu bạn ngắt thì thực hiện lại những gì tôi đang mô tả, bạn sẽ mất các tệp được chuyển. Điều mà tôi đã làm trước đây :(
Sridhar Sarnobat 16/07/2015

Khi dọn dẹp find, tôi thích điều này: find source/ -type d -empty -delete Nó mang lại cho tôi một cảm giác yên tâm kỳ lạ rằng nó sẽ không làm tắc nghẽn mọi thứ.
greyfade

10

Từ nhận xét của zany đến câu trả lời của slm ( Di chuyển tệp và xóa thư mục bằng rsync? ) Tôi muốn giới thiệu 2 lệnh này dưới dạng câu trả lời:

rsync -av --ignore-existing --remove-source-files source/ destination/ && \
find source/ -depth -type d  -empty -exec rmdir "{}" \;

Ưu điểm là, như zany đã nói, vẫn còn một số nguy hiểm liên quan đến việc sử dụng rm -rf nếu bạn không hiểu đúng hoặc cho người mới bắt đầu.

Tôi đã thêm 2 tùy chọn, -depth và -empty và trong khi tôi không chắc liệu điều này có thực sự cần thiết hay không, nó làm cho lệnh thứ 2 trở nên dễ dàng hơn cho các tình huống khác và thậm chí còn an toàn hơn (nó vẫn làm đúng nếu một số thư mục không trống và bắt đầu loại bỏ từ điểm sâu nhất trong cây thư mục)


Tại sao không chỉ -deletethay vì -exec rmdir {} \;?
cừu bay

@felling_sheep xem bình luận của user7000 trong câu trả lời của sim: khi rsync bị gián đoạn, bạn có thể mất các tệp
mit

Khi rsync bị gián đoạn, việc tìm kiếm không bao giờ bắt đầu hay không? Vì vậy, lỗi trong một rsync thứ hai không phải là một vấn đề. Nhưng -delete cũng xóa các tệp, thay vào đó rmdir không bao giờ xóa các tệp, chỉ các thư mục. Cả (-delete và rmdir) kiểm tra các thư mục nếu chúng trống trước khi xóa.
benba

Hơn nữa, các trang nam nói rằng bạn nên sử dụng -execdir thay vì -exec ...
benba

2

Điều này làm công việc trong một bước. Lưu ý dấu vết / dấu gạch chéo / trên cả đường dẫn nguồn và đích.

rsync \
    -ruval \
    --ignore-existing \
    --remove-source-files \
    --prune-empty-dirs \ 
    /source/path/ /target/path/

Tôi nhắc lại sự thận trọng từ user7000 không sử dụng --delete--remove-source-filescùng trong một cuộc gọi đến rsync. Nếu thao tác thất bại hoặc bị gián đoạn và cùng một cuộc gọi được lặp lại, bạn sẽ mất dữ liệu. Nếu nghi ngờ, hãy sử dụng --dry-runtùy chọn để xem những gì sẽ được thực hiện.


-ruvalcó vẻ dư thừa. -atương đương với -rlptgoD, bao gồm cả -r-l.
greyfade
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.