Bagaimana cara menyalin file yang masih ditulis melalui ssh?


20

Inilah situasinya:

  1. Saya mengunggah file besar dari klien A ke server menggunakan sftp.
  2. Saya juga perlu mengunduh file ini dari server ke klien B melalui ssh.

Yang ingin saya lakukan adalah memulai transfer dari server ke klien B ketika unggahan masih terjadi dari klien A.

Apa metode / alat terbaik untuk menyelesaikan ini?

PEMBARUAN :

Jawabannya sejauh ini menarik - saya pasti akan membaca dan menguji semuanya. Poin bonus untuk jawaban yang tidak bergantung pada pengontrolan cara Klien A mengunggah file. (mis. satu-satunya hal yang kita ketahui dari klien A adalah bahwa file sedang ditulis ke nama file yang dikenal.)


Ooo, pertanyaan bagus. Ini tentu saja mungkin, tetapi saya tidak mengetahui apa pun yang mengimplementasikannya
Michael Mrozek

Jawaban:


10

Untuk satu file alih-alih menggunakan SFTP Anda bisa mem-pipe file lebih dari ssh menggunakan catatau pvdi sisi pengirim dan menggunakan teepada server tengah untuk mengirim data ke file di sana dan mengirim salinan melalui tautan ssh lain di sisi lain di mana hanya menulis data ke file. Voodoo yang tepat mengharuskan saya pergi sebagai latihan untuk pembaca, karena saya tidak punya waktu untuk bermain sekarang (maaf). Metode ini hanya akan berfungsi jika tujuan kedua dapat diakses secara publik melalui SSH yang mungkin tidak seperti yang Anda gambarkan sebagai mesin klien.

Pendekatan lain, yang kurang "jalankan dan tunggu" tetapi sebaliknya mungkin lebih mudah, itu digunakan rsyncantara server dan klien B. Pertama kali Anda menjalankan ini mungkin mendapatkan salinan sebagian data, tetapi Anda bisa menjalankan kembali untuk mendapatkan lebih banyak data setelahnya (dengan satu kali jalan terakhir setelah transfer Server Client1-> selesai). Ini hanya akan berfungsi jika server menempatkan data langsung ke nama file yang benar selama transfer SFTP (kadang-kadang Anda akan melihat data masuk ke file sementara yang kemudian diganti namanya setelah file sepenuhnya ditransfer - ini dilakukan untuk membuat pembaruan file lebih banyak atom tetapi akan membuat ide rsync tidak dapat digunakan). Anda juga dapat menggunakan rsync untuk transfer C1-> S alih-alih scp (jika Anda menggunakan--inplacepilihan untuk menghindari masalah yang disebutkan di atas) - menggunakan rsync juga akan memberi Anda perlindungan terhadap keharusan mengirim ulang semuanya jika koneksi Server C1-> mengalami masalah selama transfer besar (saya cenderung menggunakan rsync --inplace -a --progress <source> <dest>bukan scp / sftp ketika rsync tersedia, untuk perilaku "transfer resume" ini).

Untuk meringkas di atas, jalankan:

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

pada client1 lalu jalankan

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

pada client2 berulang kali hingga transfer pertama selesai (lalu jalankan sekali lagi untuk memastikan Anda sudah mendapatkan semuanya). rsyncsangat baik hanya mentransfer minimum absolut yang dibutuhkan untuk memperbarui lokasi daripada mentransfer seluruh lot setiap kali. Untuk paranoia, Anda mungkin ingin menambahkan --checksumopsi ke perintah rsync (yang akan membutuhkan lebih banyak waktu CPU untuk file besar tetapi tidak akan secara signifikan menghasilkan lebih banyak data yang ditransfer kecuali diperlukan) dan untuk kecepatan --compresspilihan akan membantu jika data Anda mentransfer belum dalam format terkompresi.


5

Saya tidak dapat mencobanya saat ini, jadi ini mungkin gagal: Ide saya adalah ini: Pasang direktori di mana file tersebut tiba di klien B, misalnya dengan sshfs ke / mnt / server di sistem file klien b. Kemudian

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

/ usr / bin / tail: tidak dapat membuka `+0 'untuk membaca: Tidak ada file atau direktori seperti itu - coreutils 7.4
maxschlepzig

Maaf, ada -c yang hilang. Saya memperbaikinya dalam jawaban di atas.
fschmitt

ok, masalah yang saya lihat dengan ini adalah bahwa perintah tersebut tidak berakhir (-f -> follow ...). Seseorang harus mengeluarkan sigQUIT atau sesuatu seperti itu, ketika Anda yakin bahwa pertanyaan file sepenuhnya ditulis. Btw, tergantung pada versi ekor Anda dan fs, ekor secara internal melakukan polling file (misalnya setiap detik).
maxschlepzig

Saya punya kasus: merekam file video ke HDD saya, tetapi saya ingin menyalin ke memori USB Flash eksternal sehingga saya bisa membagikannya kepada seseorang segera setelah rekaman dihentikan. Saya mencoba beberapa rsync --appenddan kemudian diperiksa dengan md5sumtetapi file tidak pernah cocok. tail -c +0melakukan pekerjaan untuk saya. Saya juga biasa pv -pteramemantau perkembangan ekor, ini memungkinkan saya untuk melihat apakah itu berhasil. Saya belum selesai memeriksa md5s untuk memverifikasi bahwa itu berhasil, tetapi tampak hebat.
unfa

@unfa Harap perbarui komentar Anda dengan menambahkan jawaban di bawah ini (yaitu bukan komentar).
Xofo

1

Saya pikir ini harus berhasil:

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

lalu

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

Tambahkan perintah pv jika Anda ingin melihat throughput Anda.


Apakah Anda bermaksud menulis tail -c +0?
hidangan penutup

1

Anda bisa menggunakan fifo untuk itu. Untuk kesederhanaan, pertama tanpa ssh hanya melibatkan dua xterms:

Pada xterm A:

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

Di 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

Dengan ssh seharusnya ada sesuatu di sepanjang baris ini - mungkin Anda harus menonaktifkan karakter escape di ssh (-e none):

klien A:

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

klien B:

 $ ssh server cat fif > dest.tar.gz

1

Saya memiliki situasi yang memerlukan solusi seperti yang diminta poster asli. Saya merekam permainan hoki di komputer saya di satu lokasi dan saya ingin menontonnya di TV saya di lokasi lain. Tautan antara kedua lokasi memungkinkan penyalinan sekitar 1,3 MB / detik dan video rekaman sekitar 1,5 MB / detik. Jadi, saya ingin menyalin file ketika mulai merekam. Dengan cara ini permainan 3 jam saya akan menyalin dalam waktu sekitar 3,5 jam. Jadi, saya menyalinnya saat mulai merekam dan saya bisa mulai menontonnya 30 menit setelah dimulai. Maka saya bisa menontonnya tanpa gangguan, hampir secara real time. Yaitu, selama saya bisa menyalinnya saat menulis file baru. Masalah dengan alat-alat seperti rsync dan scp adalah bahwa mereka melihat ukuran file ketika Anda memulai salinan dan setelah itu menyalin jumlah data, itu berhenti; bahkan jika file tersebut tumbuh lebih dari dua kali lipat selama salinan itu. Dan, jika, saya hanya menggunakan rsync dalam satu lingkaran untuk menyalinnya setelah itu berhenti, ketika rsync berikutnya selesai itu membangun kembali file target dan yang membunuh pemutar video saya dan saya harus me-restart menontonnya dan maju cepat ke mana pun saya berada dalam program ketika tiba-tiba membunuhnya. Saya menginginkan solusi yang lebih baik dan saya belum dapat menemukannya, jadi saya menyatukan ini sebagai gantinya:

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'

Jadi apa fungsinya?

Pertama, saya menggunakan dd untuk menyalin file saat tumbuh. Karena file tumbuh lebih cepat daripada dd dapat mengirimkannya melalui jaringan, dd tidak pernah mengejar hingga akhir file. Selanjutnya, saya pipe ke "pipe viewer (pv)" dan saya berikan perkiraan seberapa besar file akan didasarkan pada seberapa besar file-file ini biasanya. Ini tidak perlu, tapi saya suka melihat meteran kemajuan. Kemudian, saya menyalurkan aliran ke koneksi ssh saya. Sambungan ssh digunakan -Cuntuk kompresi (untuk mengurangi bandwidth jaringan dan mencoba mempercepatnya), -c arcfour,blowfish-cbcuntuk enkripsi yang paling murah (sekali lagi untuk mempercepat sedikit),-padalah untuk port firewall yang saya gunakan di tujuan, dan ssh akhirnya menjalankan perintah dd pada target untuk membuat ulang file ketika menerimanya. Saya senang mengatakan, solusi ini sangat bagus. Saya bisa menonton pertandingan hoki sementara file sedang dibuat dan disalin dengan hanya penundaan singkat.


0

Saya tidak yakin bahwa metode tail -f bekerja (walaupun mungkin tidak jika file tersebut adalah teks). Alasannya adalah bahwa saya tidak tahu bagaimana tail -f, dan sftp mentransfer dan mengandalkan informasi meta.

Jika sftp mentransfer informasi meta terlebih dahulu dan tail -f bergantung pada informasi meta untuk memberi tahu bahwa tidak ada lagi file, maka tail mungkin buruk akhirnya dengan EOFs atau nulls.

Jika Anda tidak peduli dengan jalur pengunggahan, yaitu Komputer 1 mengunggah ke komputer 2 mengunggah ke komputer 3, maka Anda dapat mencoba menggunakan bittorent bukan sftp. Nampaknya itulah yang dirancang untuk itu.


0

Anda dapat mencoba membaca file dari awal tetapi Anda harus yakin bahwa Anda dapat menulisnya dengan kecepatan yang sama setidaknya.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.