Thực hành tốt nhất để tiếp tục mv


13

Tôi đã sử dụng thiết bị đầu cuối để sao chép các tập tin từ ổ đĩa này sang ổ đĩa khác.

sudo mv -vi /location/to/drive1/ /location/to/drive2/

Tuy nhiên, điều đó đột nhiên dừng lại, trong khi một vài giờ vào nó, và không có lỗi, sau khi tạo một thư mục.

Giải pháp của riêng tôi thường là kết hợp băm và so sánh phần lớn là một mớ hỗn độn tốn thời gian vì bây giờ tôi phải khôi phục từ một bản sao trung gian mà không thực sự biết tệp nào bị thiếu (được viết dưới dạng một lớp rất dài cho zsh - lưu ý rằng kịch bản này không hoạt động trong bash như được viết):

source_directory="/path/to/source_directory/";
target_directory="/path/to/target_directory/";
while read hash_and_file; do {
    echo "${hash_and_file}" | read hash file;
    echo "${file}" | sed "s/^/${source_directory}/g" | read copy_from;
    echo "${copy_from}" | sed "s/${source_directory}/${target_directory}/g" | read copy_to;
    mv -v "${copy_from}" "${copy_to}" | tee -a log;
    rm -v "${copy_from}" | tee -a log; };
done <<<$(
    comm -23 <( find ${source_directory} -type f -exec sha256sum "{}" \; |
                sed "s: ${source_directory}: :g" | sort;
           ) <( find ${target_directory} -type f -exec sha256sum "{}" \; |
                sed "s: ${target_directory}: :g" | sort; ) )

Đây là lỗi dễ xảy ra nếu thư mục đích tên hoặc source_directory là một phần của đường dẫn và xóa các tệp nếu chúng chưa được di chuyển vì chúng được đánh dấu là trùng lặp. Ngoài ra, nó không có thư mục nguồn cuối cùng.

Có một thực hành tốt nhất làm thế nào để phục hồi từ mv bị gián đoạn?


Tôi đã viết một kịch bản tương tự , sử dụng cmpthay vì băm. Nó có sự phụ thuộc và những vấn đề tương tự với while readGilles đã đề cập. Nó cũng chậm và dài dòng. Nhưng nó giải phóng không gian đĩa sớm hơn phương thức rsync, vì các tệp được (được) di chuyển khỏi nguồn khi nó chạy. Nó có thể phục vụ như là nguồn cảm hứng cho những người dũng cảm.
joeytwiddle

3
@joeytwiddle rsync cung cấp --delete-during receiver deletes during the transfervà một số lựa chọn thay thế hữu ích khác : --delete --delete-before --delete-delay --delete-after --delete-excluded. Vì vậy, vâng, rsync là sự thay thế tốt nhất,
Isaac

Chắc chắn là tôi đang thiếu gì đó. Tại sao không lặp lại cùng một mvlệnh? Có lẽ với *đường dẫn nguồn được thêm vào nếu nguồn ban đầu là một thư mục.
jpa

@isaac Không, tôi sợ rsync --delete*sẽ là một thảm họa ! Nó sẽ xóa những thứ destkhông có trong đó src, vì vậy tất cả các tệp đã được di chuyển thành công trong lần thử trước sẽ bị xóa! Bạn có thể nghĩ rằng rsync --remove-source-filestôi đồng ý sẽ là một lựa chọn tốt. ( more1 , more2 )
joeytwiddle

@joeytwiddle Không, rsync --deletesẽ chỉ xóa các tệp khác không phải là một phần của nguồn. Từ [man rsync] () * xóa các tệp không liên quan khỏi các dir dir *. Hiểu ý nghĩa ngoại lai : Không được đồng bộ hóa. Và có, rsync cũng cung cấp một cách để loại bỏ các tệp nguồn sau khi chúng được truyền chính xác.
Isaac

Câu trả lời:


46

Hãy quên việc cố gắng phát minh lại rsync và sử dụng rsync.

sudo rsync -av /location/to/drive1/ /location/to/drive2/

Hãy chắc chắn rằng bạn sử dụng dấu gạch chéo trên nguồn, nếu không nó sẽ sao chép vào /location/to/drive2/drive1.

Kiểm tra kỹ xem lệnh có thành công không, sau đó chạy rm -rf /location/to/drive1/.

Lệnh trên sẽ ghi đè lên bất kỳ tệp nào có sẵn từ đó drive2. Nếu bạn muốn nhắc người dùng bỏ qua các tệp đã tồn tại drive2, thì với mv -inó, nó phức tạp hơn, vì bây giờ bạn cần phân biệt các tệp đã được sao chép và các tệp không có. Bạn có thể chuyển --ignore-existingtùy chọn sang rsync để bỏ qua các tệp đã tồn tại trên đích đến bất kể nội dung của chúng. Lưu ý rằng nếu bản gốc mvbị gián đoạn ở giữa quá trình tạo tệp, tệp này sẽ vẫn ở trạng thái được sao chép một nửa (trong khi bản trần rsync -asẽ hoàn thành sao chép chính xác).

Nếu bạn muốn tái tạo hành vi chính xác của mv -i, bao gồm nhắc nhở, điều đó có thể được thực hiện, nhưng nó phức tạp hơn nhiều.

Lưu ý rằng lớp lót khổng lồ của bạn rất dễ vỡ. Nếu có tên tệp chứa dấu gạch chéo ngược hoặc dòng mới, chúng có thể không được sao chép đúng hoặc thậm chí chúng có thể lừa tập lệnh của bạn xóa các tệp tùy ý. Vì vậy, không sử dụng mã trong câu hỏi trừ khi bạn chắc chắn rằng bạn có thể tin tưởng tên tệp không chứa dấu gạch chéo ngược hoặc dòng mới.

Để tham khảo trong tương lai, tôi khuyên bạn không bao giờ nên sử dụng mvcho các di chuyển chéo lớn, chính xác bởi vì thật khó để kiểm soát những gì xảy ra nếu nó bị gián đoạn. Sử dụng rsync để thực hiện sao chép và sau đó xóa bản gốc.


Những gì hứa hẹn rsync làm cho mv không?
Có gì

4
tốt, ví dụ rsyncnhư những gì bạn đang cố gắng làm, trong khi mvkhông. Ngoài ra: sao chép giữa các máy khác nhau; nén để chuyển; bỏ qua các tệp hiện có tại đích dựa trên sự bình đẳng dựa trên dấu thời gian hoặc hàm băm; cấu hình xử lý quyền sở hữu, quyền, liên kết và các tập tin đặc biệt; v.v. linux.die.net/man/1/rsync
Silly Freak

1
@SillyFreak tôi nên kết luận từ đó, rằng tôi nên luôn luôn sử dụng rsync thay vì mv, không chỉ như Gilles đã nói cho ổ đĩa chéo, mà bất kỳ hoạt động nào, vì ranh giới của "quá lớn" là tương đối chủ quan và nếu nó gặp vấn đề nó sẽ được giải quyết bằng rsync nào?
Có gì

9
tốt, khi tôi di chuyển tệp hoặc thư mục trong một phân vùng, tôi thường sử dụng mv(hoặc trình quản lý tệp) vì nó chỉ di chuyển một tham chiếu đến tệp / thư mục. Nếu tôi cần thực hiện chuyển dữ liệu thực tế, thì tôi sẽ sử dụng rsyncnếu một trong những điều sau đây là đúng: 1) Tôi đang di chuyển nhiều tệp hơn tôi có thể kiểm tra chuyển chính xác trong nháy mắt; 2) Tôi dự đoán rằng tôi sẽ cần giữ các tệp đồng bộ; 3) Tôi hy vọng việc chuyển tiền có thể bị gián đoạn. Quan điểm của tôi là, đối với các trường hợp sử dụng bạn đang trình bày trong câu hỏi, rsyncchỉ đơn giản là công cụ thích hợp, và mvhoặc cplà không.
Silly Freak

7
Tôi sẽ khuyên bạn luôn luôn chạy bất kỳ lệnh rsync nào với -v và trước đó là chạy để xác nhận chính xác những gì nó sẽ làm.
Darren
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.