Tại chỗ trích xuất lưu trữ tar


14

Tôi có một chút khó xử ở đây ...

Tôi cần phải di chuyển các tệp có giá trị khoảng 70 GB từ một trong các máy chủ của mình sang máy chủ khác, vì vậy tôi đã quyết định rằng bỏ qua chúng và gửi tệp lưu trữ sẽ là cách nhanh nhất.

Tuy nhiên, máy chủ nhận chỉ còn 5 GB dung lượng sau khi nhận được kho lưu trữ tar.

Có cách nào để tôi có thể trích xuất tar 'tại chỗ' không? Tôi không cần phải lưu trữ sau khi nó được giải nén, vì vậy tôi đã tự hỏi liệu có thể làm điều này không.

Chỉnh sửa: Cần lưu ý rằng kho lưu trữ đã được gửi và tôi muốn tránh gửi lại thông qua một phương thức khác.

Câu trả lời:


11
% tar czf - stuff_to_backup | ssh backupmachine tar xvzf -

điều này dịch là:

  • tar và nén 'Stuff_to_backup' vào thiết bị xuất chuẩn
  • đăng nhập vào 'backupmachine' qua ssh
  • chạy 'tar' trên 'backupmachine' và gỡ bỏ những thứ đến từ stdin

Cá nhân tôi sẽ sử dụng 'rsync over ssh' để chuyển nội dung vì bạn có thể tiếp tục chuyển nội dung nếu kết nối bị ngắt:

% rsync -ar --progress -e 'ssh' 'stuff_to_backup' user@backupmachine:/backup/

sẽ chuyển mọi thứ từ 'Stuff_to_backup' sang thư mục 'backup' trên 'backupmachine'. nếu kết nối bị ngắt, chỉ cần lặp lại lệnh. nếu một số tệp trong 'Stuff_to_backup' thay đổi, hãy lặp lại nội dung, chỉ có sự khác biệt sẽ được chuyển.


Xem câu hỏi đã được chỉnh sửa của tôi
kẻ hèn nhát ẩn danh

@Charlie Somerville: vâng, bạn đã bỏ phần quan trọng ra ngay từ đầu. :)
akira

6

Nếu máy khác có ssh, tôi sẽ khuyên bạn nên rsync như một giải pháp thay thế khác không sử dụng tệp tar:

rsync -avPz /some/dir/ user@machine:/some/other/dir/

Và hãy cẩn thận với hàng đầu /

Chỉnh sửa cập nhật

Chà, tôi thấy làm thế nào bây giờ là một dưa chua tuyệt vời nếu bạn không thể xóa nó và giới thiệu với rsync. Tôi có thể sẽ thử một trích xuất chọn lọc và xóa khỏi tar.

trích xuất chọn lọc:

$ tar xvf googlecl-0.9.7.tar googlecl-0.9.7/README.txt
googlecl-0.9.7/README.txt

xóa chọn lọc:

$ tar --delete --file=googlecl-0.9.7.tar googlecl-0.9.7/README.txt

Tuy nhiên, có vẻ như bạn sẽ dành nhiều thời gian để mã hóa một kịch bản cho việc này ...


Xem câu hỏi đã được chỉnh sửa của tôi
kẻ hèn nhát ẩn danh

Xem câu trả lời đã được chỉnh sửa của tôi ... chúc may mắn: - /
YuppieNetworking

Cảm ơn đã chỉnh sửa. Các tệp thực sự được đặt tên bằng số, do đó, một vòng lặp nhanh trong bash có thể chỉ thực hiện thủ thuật.
kẻ hèn nhát vô danh

1
@Charlie Somerville: bạn có thể phải bắt đầu với các tệp được lưu trữ ở cuối tar, nếu không bạn có thể kết thúc bằng tar tạo một kho lưu trữ mới ... vì vậy, trước tiên hãy xóa các tệp khỏi cuối tar.
akira

5

Về cơ bản, những gì bạn cần là khả năng chuyển tập tin thành tar và "lop" phía trước khi bạn đi.

Trên StackOverflow, ai đó đã hỏi làm thế nào để cắt một tệp ở phía trước , nhưng dường như điều đó là không thể. Bạn vẫn có thể điền vào phần đầu của tệp bằng các số 0 theo cách đặc biệt để tệp trở thành một tệp thưa thớt , nhưng tôi không biết làm thế nào để làm điều này. Chúng tôi có thể cắt ngắn phần cuối của tập tin. Nhưng tar cần đọc lưu trữ về phía trước, không phải ngược lại.

Giải pháp 1

Một mức độ của sự quyết định giải quyết mọi vấn đề. Đầu tiên đảo ngược tệp tại chỗ, sau đó đọc ngược lại (điều này sẽ dẫn đến việc đọc tệp gốc chuyển tiếp) và cắt ngắn phần cuối của tệp bị đảo ngược khi bạn đi.

Bạn sẽ cần phải viết một chương trình (c, python, bất cứ thứ gì) để trao đổi phần đầu và phần cuối của tệp, chunk by chunk, và sau đó chuyển các đoạn này thành tar trong khi cắt một đoạn một lúc. Đây là cơ sở cho giải pháp 2 có thể đơn giản hơn để thực hiện.

Giải pháp 2

Một phương pháp khác là chia tệp thành các phần nhỏ tại chỗ , sau đó xóa các phần đó khi chúng tôi giải nén chúng. Mã dưới đây có kích thước chunk một megabyte, điều chỉnh tùy theo nhu cầu của bạn. Lớn hơn nhanh hơn nhưng sẽ chiếm nhiều không gian trung gian hơn khi tách và trong quá trình trích xuất.

Tách tập tin archive.tar:

archive="archive.tar"
chunkprefix="chunk_"
# 1-Mb chunks :
chunksize=1048576

totalsize=$(wc -c "$archive" | cut -d ' ' -f 1)
currentchunk=$(((totalsize-1)/chunksize))
while [ $currentchunk -ge 0 ]; do
    # Print current chunk number, so we know it is still running.
    echo -n "$currentchunk "
    offset=$((currentchunk*chunksize))
    # Copy end of $archive to new file
    tail -c +$((offset+1)) "$archive" > "$chunkprefix$currentchunk"
    # Chop end of $archive
    truncate -s $offset "$archive"
    currentchunk=$((currentchunk-1))
done

Chuyển các tệp đó thành tar (lưu ý chúng ta cần biến chunkprefix trong terminal thứ hai):

mkfifo fifo
# In one terminal :
(while true; do cat fifo; done) | tar -xf -
# In another terminal :
chunkprefix="chunk_"
currentchunk=0
while [ -e "$chunkprefix$currentchunk" ]; do
    cat "$chunkprefix$currentchunk" && rm -f "$chunkprefix$currentchunk"
    currentchunk=$((currentchunk+1))
done > fifo
# When second terminal has finished :
# flush caches to disk :
sync
# wait 5 minutes so we're sure tar has consumed everything from the fifo.
sleep 300
rm fifo
# And kill (ctrl-C) the tar command in the other terminal.

Vì chúng tôi sử dụng một đường ống có tên ( mkfifo fifo), bạn không cần phải đặt tất cả các khối cùng một lúc. Điều này có thể hữu ích nếu bạn thực sự kín về không gian. Bạn có thể làm theo các bước sau:

  • Di chuyển, giả sử các khối 10Gb cuối cùng sang đĩa khác,
  • Bắt đầu khai thác với các đoạn bạn vẫn có,
  • Khi while [ -e … ]; do cat "$chunk…; donevòng lặp kết thúc (thiết bị đầu cuối thứ hai):
  • KHÔNG dừng tarlệnh, KHÔNG loại bỏ fifo (thiết bị đầu cuối đầu tiên), nhưng bạn có thể chạy sync, chỉ trong trường hợp,
  • Di chuyển một số tệp được giải nén mà bạn biết là đã hoàn tất (tar không bị đình trệ khi chờ dữ liệu hoàn tất giải nén các tệp này) sang đĩa khác,
  • Di chuyển các phần còn lại trở lại,
  • Tiếp tục khai thác bằng cách chạy lại các while [ -e … ]; do cat "$chunk…; donedòng.

Tất nhiên đây là tất cả điện áp , bạn sẽ muốn kiểm tra mọi thứ đều ổn trên kho lưu trữ giả trước, vì nếu bạn mắc lỗi thì tạm biệt dữ liệu .

Bạn sẽ không bao giờ biết thiết bị đầu cuối ( tar) thực sự đã xử lý xong nội dung của fifo hay chưa, vì vậy nếu bạn thích, bạn có thể chạy cái này thay vào đó, nhưng bạn sẽ không có khả năng trao đổi liền mạch với các đĩa khác:

chunkprefix="chunk_"
currentchunk=0
while [ -e "$chunkprefix$currentchunk" ]; do
    cat "$chunkprefix$currentchunk" && rm -f "$chunkprefix$currentchunk"
    currentchunk=$((currentchunk+1))
done | tar -xf -

Khước từ

Lưu ý rằng để tất cả điều này hoạt động, vỏ, đuôi và cắt của bạn phải xử lý chính xác các số nguyên 64 bit (bạn không cần máy tính 64 bit cũng như hệ điều hành cho việc đó). Của tôi thì có, nhưng nếu bạn chạy đoạn script trên trên một hệ thống không có các yêu cầu này, bạn sẽ mất tất cả dữ liệu trong archive.tar .

Và trong mọi trường hợp có điều gì đó không ổn, bạn sẽ mất tất cả dữ liệu trong archive.tar, vì vậy hãy đảm bảo bạn có bản sao lưu dữ liệu của mình.


0

Nếu bạn có các tệp đối tượng được di chuyển qua, hãy thử tước chúng. Điều này sẽ tiết kiệm một lượng không gian đáng kể.

$ strip `find . -name "*.bin"`
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.