まだsshで書き込まれているファイルをコピーする方法は?


20

状況は次のとおりです。

  1. sftpを使用して、クライアントAからサーバーに大きなファイルをアップロードしています。
  2. また、このファイルをサーバーからssh経由でクライアントBにダウンロードする必要があります。

クライアントAからのアップロードがまだ行われているときに、サーバーからクライアントBへの転送を開始します。

これを達成するための最良の方法/ツールは何ですか?

更新

これまでの回答は興味深いものです。必ずすべてを読んでテストしてください。クライアントAがファイルをアップロードする方法を制御することに依存しない回答に対するボーナスポイント。(つまり、クライアントAからわかっているのは、ファイルが既知のファイル名に書き込まれていることだけです。)


いい質問ですね これは確かに可能ですが、私はそれを実装するものを知りません
マイケル・ムロゼック

回答:


10

SFTPを使用する代わりに単一のファイルの場合、送信側catまたはpv送信側でsshを介してファイルをパイプ処理teeし、中間サーバーで使用してデータをそこにファイルに送信し、もう一方のsshリンクを介してコピーを送信することができますデータをファイルに書き込むだけです。正確なブードゥーが必要だったので、今すぐプレイする時間がないので、読者のために演習として残しておきます(申し訳ありません)。この方法は、2番目の宛先がSSHを介してパブリックにアクセスできる場合にのみ機能しますが、クライアントマシンとして説明する場合はそうではありません。

「実行と待機」は少ないが、それ以外の方が簡単な別のアプローチrsyncは、サーバーとクライアントBの間で使用することです。これを初めて実行すると、データの部分的なコピーを取得できますが、再実行することができますその後、より多くのデータを取得します(Client1-> Serverの転送が完了したら、最後に1回実行します)。これは、サーバーがSFTP転送中にデータを正しいファイル名に直接入れた場合にのみ機能します(ファイルが完全に転送されると名前が変更される一時ファイルにデータが移動する場合があります-これは、ファイルの更新はよりアトミックですが、rsyncのアイデアは使用できなくなります)。scpの代わりにC1-> S転送にrsyncを使用することもできます(使用する場合--inplace上記の問題を回避するためのオプション)-rsyncを使用すると、C1-> Server接続で大規模な転送中に問題が発生した場合に、すべてを再送信する必要がなくなります(rsync --inplace -a --progress <source> <dest>rsyncが利用可能な場合、scp / sftpの代わりに使用する傾向があります。この「転送再開」動作)。

上記を要約するには、次を実行します:

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

client1で実行中

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

最初の転送が完了するまで、client2で繰り返し実行します(すべて実行できるようにもう一度実行します)。rsync毎回ロット全体を転送するのではなく、ロケーションを更新する必要がある絶対最小値のみを転送するのが非常に得意です。パラノイアのためには、追加したい場合があります--checksum(大きなファイルのためのより多くのCPU時間がかかりますが、それが必要とされない限り、はるかに多くのデータが転送されてにはなりません)のrsyncコマンドにオプションを、スピードのための--compressデータならばオプションが役立ちます転送するファイルはまだ圧縮形式ではありません。


5

現時点では試すことができないので、これは失敗する可能性があります。私の考えは次のとおりです。たとえば、クライアントBのファイルシステムの/ mnt / serverにsshfsを使用して、ファイルがクライアントBに到着するディレクトリをマウントします。それから

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

/ usr / bin / tail:読み取りのために「+0」を開くことができません:そのようなファイルまたはディレクトリはありません
-coreutils

申し訳ありませんが、-cがありません。上記の答えで修正しました。
-fschmitt

わかりました、これで私が見る問題は、コマンドが終了しないことです(-f-> follow ...)。fileinquestionが完全に記述されていることが確実な場合、sigQUITまたはそのようなものを発行する必要があります。ところで、tailバージョンとfsに応じて、tailは内部的にファイルのポーリングを行います(たとえば、毎秒)。
-maxschlepzig

私は、HDDにビデオファイルを記録するケースがありましたが、記録が停止されたらすぐに人に渡すことができるように、外部USBフラッシュメモリにコピーしたかったのです。複数回試してrsync --appendから確認しましたmd5sumが、ファイルが一致しませんでした。tail -c +0私のために仕事をしました。私はまたpv -ptera、尾の進行状況を監視していました。私はまだmd5をチェックして、それが機能したことを確認していませんでしたが、見栄えは良いです。
unfa

@unfa以下の回答(コメントではない)を追加して、コメントを更新してください。
Xofo

1

私はこれがうまくいくと思う:

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

その後

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

スループットを確認する場合は、pvコマンドを追加します。


書くつもりtail -c +0ですか?
デザート

1

fifoを使用できます。2つのxtermのみを含むsshを使用せずに、最初に簡単にするために:

xterm Aで:

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

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

sshでは、これらの行に沿ったものになるはずです-おそらく、sshでエスケープ文字を無効にする必要があります(-e none):

クライアントA:

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

クライアントB:

 $ ssh server cat fif > dest.tar.gz

1

元のポスターのような解決策が必要な状況があります。ある場所のコンピューターでホッケーの試合を録画していますが、別の場所のテレビで見たいです。2つの場所間のリンクにより、コピーは約1.3Mb / sで、録画ビデオは約1.5Mb / sになります。それで、記録を開始するときにファイルをコピーしたいと思います。このようにして、私の3時間のゲームは約3.5時間でコピーされます。そのため、録音を開始するときにコピーし、開始してから30分後に視聴を開始できます。そうすれば、ほぼリアルタイムで中断することなく視聴できます。つまり、新しいファイルを書き込むときにコピーすることができる限りです。rsyncやscpなどのツールの問題は、コピーを開始するときにファイルのサイズを確認し、その量のデータをコピーすると終了することです。そのコピー中にファイルが2倍以上大きくなったとしても。そして、もし私がループでrsyncを使用して停止したらコピーし、次のrsyncが終了するとターゲットファイルを再構築し、それが私のビデオプレーヤーを殺しますプログラムで突然それを殺したとき。より良い解決策が欲しかったのですが、見つけることができなかったので、代わりにこれをつなぎ合わせました。

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'

それで、これは何をしますか?

まず、ddを使用して、ファイルが大きくなるにつれてコピーします。ファイルはddがネットワークを介して送信するよりも速く成長するため、ddはファイルの最後まで追いつくことはありません。次に、それを「パイプビューアー(pv)」にパイプし、これらのファイルの通常の大きさに基づいて、ファイルの大きさを推定します。これは必須ではありませんが、進行状況メーターが表示されます。次に、ssh接続にストリームをパイプします。ssh接続は-C、圧縮(ネットワーク帯域幅を減らして高速化するため)、-c arcfour,blowfish-cbc最も安価な暗号化(ここでも少し高速化するため)、-p宛先で使用しているファイアウォールポート用です。sshは最終的にターゲットでddコマンドを実行し、受信したファイルを再作成します。このソリューションは非常に効果的です。ファイルを作成してコピーしている間、ホッケーの試合を少しの遅延で見ることができます。


0

tail -fメソッドが機能するかどうかはわかりません(ファイルがテキストの場合はおそらく機能します)。理由は、tail -f、sftpがどのように転送され、メタ情報に依存するかがわからないからです。

sftpが最初にメタ情報を転送し、tail -fがメタ情報に依存してファイルがもうないことを伝える場合、tailはEOFまたはnullで終了を無効にする可能性があります。

アップロードのパスを気にしない場合、つまり、コンピューター1からコンピューター2へのアップロード、コンピューター3へのアップロードなど、sftpではなくbittorentを使用してみてください。それはそれが設計されたものであるようです。


0

ファイルを最初から読み取ろうとすることはできますが、少なくとも同じ速度で書き込むことができることを確認する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.