Làm cách nào để chỉ sao chép các thuộc tính tệp (siêu dữ liệu) mà không có nội dung thực sự của tệp?


21

Tôi đã sao chép terabyte tệp với rsyncnhưng tôi quên sử dụng --archiveđể bảo toàn các thuộc tính đặc biệt của tệp.

Tôi đã thử thực hiện rsynclại lần này với --archivenhưng nó chậm hơn so với những gì tôi mong đợi. Có cách nào dễ dàng để làm điều này nhanh hơn bằng cách sao chép siêu dữ liệu theo cách đệ quy không?


Với "siêu dữ liệu", bạn có nghĩa là quyền tệp và quyền sở hữu tệp hoặc những thứ phức tạp hơn như thuộc tính tệp mở rộng?
Marcel Promotionberg

Hệ thống tập tin nơi tập tin nguồn được gắn kết cục bộ hay không?
enzotib

theo siêu dữ liệu tôi có nghĩa là quyền và dấu thời gian. tem thời gian là đặc biệt quan trọng đối với tôi.
Mohammad

hệ thống fils cả trong nguồn và đích được gắn cục bộ.
Mohammad

Câu trả lời:


17

Ok, bạn có thể sao chép chủ sở hữu, nhóm, sự cho phép và timestamps bằng cách sử dụng --referencetham số để chown, chmod, touch. Đây là một kịch bản để làm như vậy

#!/bin/bash
# Filename: cp-metadata

myecho=echo
src_path="$1"
dst_path="$2"

find "$src_path" |
  while read src_file; do
    dst_file="$dst_path${src_file#$src_path}"
    $myecho chmod --reference="$src_file" "$dst_file"
    $myecho chown --reference="$src_file" "$dst_file"
    $myecho touch --reference="$src_file" "$dst_file"
  done

Bạn nên chạy nó với sudo(để cho phép chown) và với hai tham số: thư mục nguồn và đích. Kịch bản chỉ lặp lại những gì nó sẽ làm. Nếu hài lòng thay đổi dòng myecho=echovới myecho=.


1
Vâng, đó là những gì tôi cần: - phản ứng trong chmod. Cảm ơn bạn. Và tôi thực sự đánh giá cao nó nếu bất cứ ai có thể giới thiệu một cái gì đó như chmod - phản hồi cho việc sao chép tem thời gian.
Mohammad

1
@Mohammad: cho rằng bạn có thể sử dụng touch --reference=otherfile file. Cập nhật câu trả lời
enzotib

Thật tuyệt. Trên thực tế tôi vừa đọc hướng dẫn sử dụng cảm ứng ;-)
Mohammad

Chỉ cần lưu ý: touchtheo thiết kế chỉ thay đổi thời gian sửa đổi và truy cập, thời gian "tạo" không bị ảnh hưởng. (Tôi nghĩ rằng ext2 / 3 không hỗ trợ thay đổi ctime, nhưng điều đó có thể quan trọng nếu bạn đang sử dụng NTFS hoặc tương tự).
Amro

Trong trường hợp bạn muốn chỉ thay đổi siêu dữ liệu của các tệp hiện có và không cần đảm bảo sự tồn tại của các tệp, hãy thêm một -ccông tắc vào touchlệnh để ngăn chặn nó tạo các tệp trống trong $dst_path.
Synchro

5

CẢNH BÁO: Không có cách giải quyết đặc biệt, GNU cp --attributes-onlysẽ cắt bớt các tệp đích, ít nhất là trong Chính xác. Xem chỉnh sửa dưới đây.

Nguyên:

Trong tình huống này, bạn có thể muốn --attributes-onlytùy chọn GNU cp , cùng với --archive, vì nó đã thử và kiểm tra mã, tất cả các thuộc tính không biết hệ thống tập tin và không tuân theo các liên kết tượng trưng (theo chúng có thể xấu!):

cp --archive --attributes-only /source/of/failed/backup/. /destination/

Cũng như các tệp, cplà phụ gia với các thuộc tính mở rộng: nếu cả nguồn và đích đều có thuộc tính mở rộng thì nó sẽ thêm thuộc tính mở rộng của nguồn vào đích (thay vì xóa tất cả các xattrs của đích trước). Mặc dù điều này phản ánh cách cphành xử nếu bạn sao chép tệp vào một cây hiện có, nó có thể không như bạn mong đợi.

Cũng lưu ý rằng nếu bạn không bảo quản các liên kết cứng lần đầu tiên rsyncnhưng muốn giữ chúng ngay bây giờ thì cp bạn sẽ không khắc phục điều đó cho bạn; Bạn có lẽ tốt nhất nên chạy lại rsyncvới các tùy chọn phù hợp (xem câu trả lời khác của tôi ) và kiên nhẫn.

Nếu bạn tìm thấy câu hỏi này trong khi tìm cách để cố tình siêu dữ liệu riêng biệt và tái kết hợp / nội dung tập tin sau đó bạn có thể muốn có một cái nhìn tại metastore đó là trong kho của Ubuntu.

Nguồn: Hướng dẫn sử dụng GNU coreutils


Chỉnh sửa để thêm:

cptừ GNU coreutils> = 8.17 trở lên sẽ hoạt động như mô tả, nhưng coreutils <= 8.16 sẽ cắt bớt các tệp khi khôi phục siêu dữ liệu của chúng. Nếu nghi ngờ, không sử dụng cptrong tình huống này; sử dụng rsyncvới các tùy chọn phù hợp và / hoặc kiên nhẫn.

Tôi sẽ không khuyến nghị điều này trừ khi bạn hoàn toàn hiểu những gì bạn đang làm, nhưng GNU trước đó cpcó thể được ngăn chặn cắt bớt các tệp bằng thủ thuật LD_PRELOAD :

/*
 * File: no_trunc.c
 * Author: D.J. Capelis with minor changes by Zak Wilcox
 *
 * Compile:
 * gcc -fPIC -c -o no_trunc.o no_trunc.c
 * gcc -shared -o no_trunc.so no_trunc.o -ldl
 *
 * Use:
 * LD_PRELOAD="./no_trunc.so" cp --archive --attributes-only <src...> <dest>
 */

#define _GNU_SOURCE
#include <dlfcn.h>
#define _FCNTL_H
#include <bits/fcntl.h>

extern int errorno;

int (*_open)(const char *pathname, int flags, ...);
int (*_open64)(const char *pathname, int flags, ...);

int open(const char *pathname, int flags, mode_t mode) {
        _open = (int (*)(const char *pathname, int flags, ...)) dlsym(RTLD_NEXT, "open");
        flags &= ~(O_TRUNC);
        return _open(pathname, flags, mode);
}

int open64(const char *pathname, int flags, mode_t mode) {
        _open64 = (int (*)(const char *pathname, int flags, ...)) dlsym(RTLD_NEXT, "open64");
        flags &= ~(O_TRUNC);
        return _open64(pathname, flags, mode);
}

errornonên errno, phải không?
enzotib

Một thử nghiệm nhanh loại bỏ nó dường như có hiệu quả, vì vậy tôi đoán rằng tôi đã khắc phục được sự dư thừa / sai sót trong bản gốc , nhưng bây giờ mọi người sẽ ở trên coreutils mới hơn.
ZakW

nhưng những gì bạn gọi rsyncvới các tùy chọn phù hợp là một câu trả lời cho một câu hỏi khác ...
Jean Paul

5

Xử lý câu hỏi là "rsync chỉ có siêu dữ liệu để sao chép, vậy tại sao nó lại chậm như vậy và làm cách nào tôi có thể làm cho nó nhanh hơn?":

rsyncthường sử dụng mtimes bằng nhau như một heuristic để phát hiện và bỏ qua các tệp không thay đổi. Nếu không --archive(cụ thể là không có --times) mtimes của tệp đích vẫn được đặt thành thời gian bạn rsync-ed chúng, trong khi mtimes của tệp nguồn vẫn còn nguyên (bỏ qua thủ thuật thủ công của bạn). Không có sự đảm bảo bên ngoài từ bạn rằng nội dung của các tệp nguồn không thay đổi, rsync phải cho rằng chúng có thể có và do đó phải kiểm tra lại chúng và / hoặc sao chép chúng vào đích một lần nữa. Điều này, cộng với thực tế --whole-fileđược ngụ ý cho các đồng bộ cục bộ-> cục bộ, thực hiện rsyncmà không --timestương đương cpvới các đồng bộ cục bộ.

Với điều kiện là việc cập nhật nội dung của tệp đích có thể được chấp nhận hoặc nếu các tệp nguồn chưa được xử lý kể từ bản sao gốc, bạn sẽ tìm thấy rsync --archive --size-onlynhanh hơn một rsync ngây thơ.

Nếu nghi ngờ về những gì rsyncđang sao chép quá lâu, hãy rsync --archive --dry-run --itemize-changes ...nói với bạn một cách đầy đủ, nếu ngắn gọn, chi tiết.


1
Thông tin rất hữu ích. --archive --size-only là một kết hợp tuyệt vời. Nó không chỉ ngăn chặn các tập tin sao chép đã tồn tại ở đích mà còn cập nhật siêu dữ liệu của chúng. Điều này thật bất ngờ đối với tôi, bởi vì trang man của rsync mô tả - chỉ có kích thước là các tệp "bỏ qua" có kích thước khớp với nhau. Hóa ra là nó chỉ bỏ qua bản sao, nhưng vẫn sẽ đồng bộ siêu dữ liệu. Lý tưởng.
Chad von Nau

2

Trong chuyển cục bộ, khi nguồn và đích nằm trên các hệ thống tệp được gắn cục bộ, rsyncsẽ luôn sao chép toàn bộ nội dung tệp. Để tránh điều này, bạn có thể sử dụng

rsync -a --no-whole-file source dest

Tôi đã thử rsync với --no-Whole-file và --prowards và tôi vẫn có thể thấy tiến trình sao chép (khoảng 30 MB / s); Vì vậy, tôi đoán nó không đủ nhanh, chưa. Tôi đang mất hy vọng vào rsync ...
Mohammad

Tùy chọn này được sử dụng để yêu cầu rsynckhông sử dụng phím tắt khi các tệp nằm trong đường dẫn cục bộ, nhưng nó không ngăn chặn rsyncviệc sao chép nội dung.
Jean Paul

1

Tôi đã phải làm điều này từ xa đến một máy tính khác vì vậy tôi không thể sử dụng -

Tôi đã sử dụng điều này để tạo kịch bản ...

find -printf "touch -d \"%Tc\" \"%P\"\n" >/tmp/touch.sh

Nhưng hãy chắc chắn rằng không có bất kỳ tên tập tin nào có "trong đó trước tiên ...

find | grep '"'

Sau đó sao chép touch.sh vào máy tính từ xa của bạn và chạy ...

cd <DestinationFolder>; sh /tmp/touch.sh

Ngoài ra còn có các tùy chọn trong find -printf để in tên người dùng, tên nhóm nếu bạn muốn sao chép chúng.


Cảm ơn các ý tưởng cho a) "chỉ sử dụng tập lệnh shell" và b) để tạo tập lệnh đã nói bằng cách sử dụng find. Tôi đã ở trong tình huống tương tự - quên sao chép các thuộc tính, đĩa nguồn và đĩa đích đã có trong các máy khác nhau và không thực sự muốn đảo ngược điều đó.
i336_
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.