Làm cách nào để sao chép một tập tin vẫn đang được ghi trên ssh?


20

Đây là tình huống:

  1. Tôi đang tải một tệp lớn từ máy khách A lên máy chủ bằng sftp.
  2. Tôi cũng cần tải tập tin này từ máy chủ về máy khách B qua ssh.

Những gì tôi muốn làm là bắt đầu chuyển từ máy chủ sang máy khách B khi quá trình tải lên vẫn đang diễn ra từ máy khách A.

Phương pháp / công cụ tốt nhất để thực hiện điều này là gì?

CẬP NHẬT :

Các câu trả lời cho đến nay rất thú vị - Tôi chắc chắn sẽ đọc và kiểm tra tất cả. Điểm thưởng cho câu trả lời không phụ thuộc vào việc kiểm soát cách khách hàng A tải lên tệp. (tức là điều duy nhất chúng ta biết từ máy khách A là tệp đang được ghi vào một tên tệp đã biết.)


Ooo, câu hỏi hay. Điều này chắc chắn là có thể, nhưng tôi không biết bất cứ điều gì thực hiện nó
Michael Mrozek

Câu trả lời:


10

Đối với một tệp duy nhất thay vì sử dụng SFTP, bạn có thể chuyển tệp qua ssh bằng cách sử dụng cathoặc pvở phía gửi và sử dụng teetrên máy chủ giữa để gửi dữ liệu tới một tệp ở đó và gửi một bản sao qua liên kết ssh khác ở phía bên kia chỉ ghi dữ liệu vào một tập tin Voodoo chính xác yêu cầu tôi sẽ để lại như một bài tập cho người đọc, vì tôi không có thời gian để chơi ngay bây giờ (xin lỗi). Phương pháp này sẽ chỉ hoạt động nếu đích thứ hai có thể truy cập công khai qua SSH, có thể không phải là trường hợp như bạn mô tả nó như một máy khách.

Một cách tiếp cận khác, ít "chạy và chờ" hơn nhưng có thể dễ sử dụng hơn, nó được sử dụng rsyncgiữa máy chủ và máy khách B. Lần đầu tiên bạn chạy nó có thể nhận được một phần dữ liệu, nhưng bạn chỉ có thể chạy lại nó để có thêm dữ liệu sau đó (với một lần chạy cuối cùng sau khi quá trình chuyển Client1-> Server hoàn tất). Điều này sẽ chỉ hoạt động nếu máy chủ đặt dữ liệu trực tiếp vào đúng tên tệp trong quá trình chuyển SFTP (đôi khi bạn sẽ thấy dữ liệu đi vào một tệp tạm thời sau đó được đổi tên sau khi tệp được chuyển hoàn toàn - việc này được thực hiện để thực hiện cập nhật tệp nguyên tử hơn nhưng sẽ khiến ý tưởng rsync không sử dụng được). Bạn cũng có thể sử dụng rsync cho chuyển C1-> S thay vì scp (nếu bạn sử dụng--inplacetùy chọn để tránh sự cố được đề cập ở trên) - sử dụng rsync cũng sẽ bảo vệ bạn khỏi việc phải gửi lại mọi thứ nếu kết nối C1-> Máy chủ gặp sự cố trong khi chuyển khoản lớn (tôi có xu hướng sử dụng rsync --inplace -a --progress <source> <dest>thay vì scp / sftp khi rsync khả dụng hành vi "chuyển tiếp" này).

Để tóm tắt ở trên, chạy:

rsync --inplace -a --progress <source> user@server:/<destination_file_or_folder>

trên client1 rồi chạy

rsync --inplace -a --progress user@server:/<destination_file_or_folder> <destination_on_cli2>

trên client2 liên tục cho đến khi quá trình chuyển đầu tiên hoàn tất (sau đó chạy một lần nữa để đảm bảo bạn đã có mọi thứ). rsynclà rất tốt khi chỉ chuyển tối thiểu tuyệt đối nó cần cập nhật một vị trí thay vì chuyển toàn bộ lô mỗi lần. Đối với chứng hoang tưởng, bạn có thể muốn thêm --checksumtùy chọn vào các lệnh rsync (sẽ tốn nhiều thời gian CPU hơn cho các tệp lớn nhưng sẽ không dẫn đến việc truyền dữ liệu nhiều hơn đáng kể trừ khi cần thiết) và để tăng tốc độ --compresstùy chọn sẽ giúp ích nếu dữ liệu bạn đang chuyển chưa ở định dạng nén.


5

Tôi không thể thử nó vào lúc này, vì vậy điều này có thể thất bại: Ý tưởng của tôi là thế này: Gắn thư mục chứa tệp đến máy khách B, ví dụ với sshfs đến / mnt / server trong hệ thống tệp của máy khách b. Sau đó

tail -c +0 -f /mnt/server/thefileinquestion > ~/finalfile

/ usr / bin / tail: không thể mở `+0 'để đọc: Không có tệp hoặc thư mục như vậy - coreutils 7.4
maxschlepzig

Xin lỗi, đã có một -c mất tích. Tôi đã sửa nó trong câu trả lời ở trên.
fschmitt

ok, một vấn đề tôi thấy với điều này là lệnh không chấm dứt (-f -> follow ...). Người ta phải đưa ra một sigQUIT hoặc một cái gì đó tương tự, khi bạn chắc chắn rằng phần mềm hoàn chỉnh được viết hoàn toàn. Btw, tùy thuộc vào phiên bản đuôi và fs của bạn, đuôi bên trong thực hiện việc bỏ phiếu của tệp (ví dụ: mỗi giây).
maxschlepzig

Tôi có một trường hợp: ghi tập tin video vào ổ cứng của tôi, nhưng tôi muốn sao chép vào bộ nhớ USB Flash bên ngoài để tôi có thể đưa nó cho một người ngay khi dừng ghi. Tôi đã thử nhiều rsync --appendvà sau đó kiểm tra md5sumnhưng các tập tin không bao giờ khớp. tail -c +0đã làm công việc cho tôi. Tôi cũng đã từng pv -pteratheo dõi tiến trình của đuôi, nó cho phép tôi xem nó có hoạt động không. Tôi chưa hoàn thành để kiểm tra md5s để xác minh rằng nó hoạt động, nhưng trông rất tuyệt.
unfa

@unfa Vui lòng cập nhật bình luận của bạn bằng cách thêm câu trả lời bên dưới (nghĩa là không phải bình luận).
Xofo

1

Tôi nghĩ rằng điều này sẽ làm việc:

user@clientA:~$ cat file | ssh server "cat > dest"

và sau đó

user@clientB:~$ ssh server "tail +0 -f dest" > file

Thêm lệnh pv nếu bạn muốn xem thông lượng của bạn.


Ý của bạn là viết tail -c +0?
tráng miệng

1

Bạn có thể sử dụng fifo cho nó. Để đơn giản trước tiên mà không có ssh chỉ liên quan đến hai xterms:

Tại xterm A:

$ mkfifo fif
$ cat test.tar.gz | tee copy.tar.gz > fif

Tại xterm B:

$ cat fif > dest.tar.gz
$ cmp test.tar.gz dest.tar.gz
$ echo $?
0
$ cmp test.tar.gz copy.tar.gz
$ echo $?
0

Với ssh, nó phải là một cái gì đó dọc theo các dòng này - có lẽ bạn phải vô hiệu hóa ký tự thoát trong ssh (-e none):

khách hàng A:

 $ ssh server mkfifo fif
 $ cat src.tar.gz | ssh "tee fif > copy.tar.gz"

khách hàng B:

 $ ssh server cat fif > dest.tar.gz

1

Tôi có một tình huống cần một giải pháp như người đăng ban đầu đã hỏi. Tôi đang ghi lại một trận khúc côn cầu trên máy tính của mình ở một địa điểm và tôi muốn xem nó trên TV của mình ở một địa điểm khác. Liên kết giữa hai vị trí cho phép bản sao đạt tốc độ khoảng 1,3Mb / giây và video ghi được khoảng 1,5Mb / giây. Vì vậy, tôi muốn sao chép tập tin khi nó bắt đầu ghi. Bằng cách này, trò chơi 3 giờ của tôi sẽ sao chép trong khoảng 3,5 giờ. Vì vậy, tôi sao chép nó khi nó bắt đầu ghi và tôi có thể bắt đầu xem nó 30 phút sau khi nó bắt đầu. Sau đó tôi có thể xem nó mà không bị gián đoạn, gần như trong thời gian thực. Đó là, miễn là tôi có thể khiến nó sao chép khi nó viết tập tin mới. Vấn đề với các công cụ như rsync và scp là chúng xem kích thước của tệp khi bạn khởi tạo bản sao và một khi nó sao chép lượng dữ liệu đó, nó sẽ thoát; ngay cả khi tệp đã tăng hơn gấp đôi trong bản sao đó. Và, nếu, tôi chỉ sử dụng rsync trong một vòng lặp để sao chép nó một khi nó dừng lại, khi rsync tiếp theo hoàn thành, nó sẽ xây dựng lại tệp mục tiêu và nó sẽ giết chết trình phát video của tôi và tôi phải khởi động lại xem nó và nhanh chóng chuyển tiếp đến bất cứ nơi nào tôi đến trong chương trình khi nó bất ngờ giết chết nó. Tôi muốn một giải pháp tốt hơn và tôi đã không thể tìm thấy một giải pháp, vì vậy tôi đã cùng nhau tìm ra giải pháp này:

dd if=2031_20160514030000.mpg |
pv --size 4653819304 |
ssh -C -c arcfour,blowfish-cbc -p 5555 myserver.com 'dd of=/media/TV/2031_20160514030000.mpg'

Vậy cái này làm gì?

Đầu tiên, tôi sử dụng dd để sao chép tập tin khi nó phát triển. Vì tệp phát triển nhanh hơn dd có thể gửi qua mạng, nên dd không bao giờ bắt kịp đến cuối tệp. Tiếp theo, tôi chuyển nó thành "trình xem đường ống (pv)" và tôi ước tính nó về mức độ lớn của tệp sẽ dựa trên mức độ lớn của các tệp này. Điều này là không cần thiết, nhưng tôi muốn xem một máy đo tiến độ. Sau đó, tôi dẫn luồng đến kết nối ssh của tôi. Kết nối ssh sử dụng -Cđể nén (để giảm băng thông mạng và cố gắng tăng tốc), -c arcfour,blowfish-cbcđể mã hóa ít tốn kém nhất (một lần nữa để tăng tốc mọi thứ lên một chút),-pdành cho cổng tường lửa của tôi, tôi đang sử dụng tại đích và ssh cuối cùng chạy lệnh dd trên mục tiêu để tạo lại tệp khi nhận được. Tôi rất vui khi nói rằng, giải pháp này hoạt động rất tốt. Tôi có thể xem trò chơi khúc côn cầu trong khi tập tin đang được tạo và sao chép chỉ với một độ trễ ngắn.


0

Tôi không chắc chắn rằng phương thức tail -f hoạt động (mặc dù nó có thể thực hiện nếu tệp là văn bản). Lý do là tôi không biết làm thế nào đuôi -f, và chuyển sftp và dựa vào thông tin meta.

Nếu sftp chuyển thông tin meta trước và đuôi -f dựa vào thông tin meta để thông báo rằng không có tệp nào nữa, thì đuôi có thể làm hỏng kết thúc với EOF hoặc null.

Nếu bạn không quan tâm đến đường dẫn tải lên, tức là Máy tính 1 tải lên máy tính 2 tải lên máy tính 3, thì bạn có thể thử sử dụng hàng đầu bittorent thay vì sftp. Có vẻ như đó là những gì nó được thiết kế cho.


0

Bạn có thể cố gắng đọc tệp từ đầu nhưng bạn cần chắc chắn rằng bạn có thể viết nó với cùng tốc độ ít nhất.

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.