scpで多数の小さなファイルをコピーするにはどうすればよいですか?


59

私は数ギガバイトと数千の小さなファイルを持っているディレクトリを持っています。scpを使用してネットワーク経由で複数回コピーしたい。ソースマシンと宛先マシンのCPU時間は安価ですが、各ファイルを個別にコピーすることにより追加されるネットワークオーバーヘッドは膨大です。tar / gzipで圧縮して出荷しますが、ソースマシンのディスクが不足しています。

出力tar -czf <output> <directory>をscp にパイプする方法はありますか?そうでない場合、別の簡単な解決策はありますか?私のソースマシンは古代(SunOS)であるため、何かをインストールしたくないのです。

回答:


104

sshセッション全体でtarをパイプすることができます:

$ tar czf - <files> | ssh user@host "cd /wherever && tar xvzf -"

3
+1タールパイプソリューション。帯域幅が広くCPUが少ない場合は、圧縮フラグを削除できます(ただし、gzipはかなり軽量です)。
-Dietbuddha

2
そして、あなたは圧縮フラグを削除し、代わりに、SSH(でそれを活性化できるssh -CCompression yes~/.ssh/config)。
サムホセバー

3
このようなtarの使用を考えたことはありません。まあ、それが私がここに来る理由です!
氏Shickadance

2
このコマンドは、少し短くすることができます$ tar cz <files> | ssh user@host "cd /wherever; tar xvz"
。– carlito

2
@Gregダッシュは、コンテキストに応じてSTDINまたはSTDOUTを意味するPOSIX互換ソフトウェアの規則です。最初のダッシュは「/ dev / stdinからの読み取り」を意味し、2番目のダッシュは実際にリモートホストで実行されますが、「/ dev / stdin」を意味します。パイプとsshは、これら両方のプロセスを接続します。詳細については、unix.stackexchange.com / questions / 16357 /…を参照してください。
リチャードメッツラー

22

bzip2圧縮を使用したTarは、ネットワークとCPUの負荷をできるだけ軽減する必要があります。

$ tar -C /path/to/src/dir -jcf - ./ | ssh user@server 'tar -C /path/to/dest/dir -jxf -'

-v画面出力によりプロセスが遅くなる可能性があるため、使用しない。ただし、詳細な出力が必要な場合-jcvfは、リモート部分ではなく、tar()のローカル側で使用してください。

バックアップコピーの更新など、同じコピー先パスを繰り返しコピーする場合、最適な選択は圧縮によるrsyncです。

$ rsync -az -e ssh /path/to/src/dir/ user@server:/path/to/dest/dir/

srcパスとdestパスの両方が/で終わっていることに注意してください。繰り返しますが、意図的に-vand -Pフラグを使用しないで、詳細な出力が必要な場合は追加してください。


16

use rsync、SSHを使用します。

使用法:

rsync -aPz /source/path destination.server:remote/path

rsyncスイッチは、圧縮とI-Node情報を考慮します。-Pすべてのファイルの進行状況を表示します。

あなたは使用することができscp -C、圧縮を可能にする、が、可能な場合は、使用しますrsync


残念ながら、rsyncはソースマシンでは使用できず、sshdも使用できません。
-nmichaels

1
sshdは、クライアントマシンでのこれらの操作には必要ありません。
ポレモン

3

tarsshを使用して両端で実行できます。 善scpssh家族の一部であるので、おそらくあなたは両端にそれを持っています。

 8:03AM 12 % tar cf - some_directory | ssh dest_host "tar xf -"

ネットワークトラフィックを減らすために、gzipまたはbzip2をパイプラインに組み込む方法もあります。


3

@pdoの答えは良いですが、バッファーと適切な圧縮により速度を上げ、プログレスバーを追加できます。

多くの場合、ネットワークがボトルネックであり、速度は時間とともに変化します。したがって、データをネットワーク経由で送信する前にバッファリングするのに役立ちます。これはで実行できますpv

さらに、通常は適切な圧縮アルゴリズムを使用して速度を上げることができます。Gzip(上記で使用したような)は高速圧縮アルゴリズムですが、一般にzstandard(zstd)(および高圧縮率の場合、LZMA / LZMA2(xz)は同時に圧縮し、より高速になります。新しいxzおよびzstdにはマルチコアサポートが既に組み込まれています。複数のコアでgzipを使用するには、pizzを使用できます。

ネットワーク経由でプログレスバー、バッファリング、zstandard圧縮を使用してデータを送信する例を次に示します。

tar cf - . | pv -perabs $(du -sk . | cut -f 1)K | zstd -14 --long=31 -T0 | pv -qCB 512M | ssh user@host "cd /wherever && pv -qCB 512M | zstd -cd -T0 --long=31 | tar xf -"

1つ目pvは、進行状況(p)、推定時間(e)、転送速度(r)、平均速度(a)、転送された合計バイト数(b)を表示することです。合計サイズが推定duされ、サイズオプション(s)に追加されます。進行状況は圧縮およびバッファリングの前に測定されるため、あまり正確ではありませんが、依然として役立ちます。

zstd圧縮設定14で使用されます。この数は、ネットワークとCPUの速度に応じて増減できるため、zstdはネットワークの速度よりも少し速くなります。Haswell 3.2 GHz CPU 14に 4つのコアを搭載すると、速度は約120 MB / sになります。この例では、ロングモード31(2 GBのウィンドウを使用し、大量のRAMを必要としますが、データベースダンプの圧縮などに非常に適しています)が使用されます。T0のオプションは、コア数にスレッドの量を設定します。これらの設定は長いモードと一緒に多くのメモリを使用することに注意してください。

zstdの問題は、ほとんどのオペレーティングシステムがバージョン1.3.4以上で出荷されていないことです。このバージョンは、適切なマルチコアと長いサポートに必要です。利用できない場合、それはからコンパイルしてインストールすることができますhttps://github.com/facebook/zstdだけでmake -j4 && sudo make install。zstdの代わりに、xzまたはpigzも使用できます。xzは低速ですが、非常に良好に圧縮します(低速接続で良好)、pizz / gzipは高速ですが、あまり圧縮しません。 pvその後、再び使用されますが、バッファリングに使用します(q静かにするCため、非スプライスモード(常にバッファリングに必要B)、およびバッファサイズを設定するため)。

この例では、受信側でもバッファが使用されます。多くの場合、これは不要です(解凍とハードディスクの書き込み速度はほとんどの場合ネットワーク速度より速いため)が、通常は害もありません。


2

両端にgzipがある場合: sourcehost$ cd sourcedir && tar cf - . | gzip -c - | ssh user@destinationhost "cd destinationdir && gzip -c -d | tar xf -"

ソースマシンにgzipがない場合は、宛先で圧縮解除されていることを確認してください。 sourcehost$ cd sourcedir && tar cf - . | compress | ssh user@destinationhost "cd destdir && uncompress | tar xf -"

これは、最初に圧縮してから送信してから解凍するよりも高速で、どちらの側にも余分なディスク領域は必要ありません。たぶんあなたはおそらく古代の側にそれを持っていないので、私はtarの圧縮(z)フラグをスキップしました。


2

または、必要に応じて他の方法で行うこともできます。それは、提案されているようにプッシュするのではなく、ネットワーク上でtarballをプルすることです。これは質問の繰り返し部分を解決するものではなく、rsyncが最適です。しかし、おそらくtarスイッチが役立つでしょう。

ローカルマシンで:

ssh remote 'tar zcf - /etc/resolv.conf' | tar zxf -

最初に正しいディレクトリに移動するか、最後に展開コマンドで-Cスイッチを使用する必要があります。

これが必要な場合にのみ言及してください。私の状況では、私のローカルサーバーはnatの背後にあるので、以前に述べた方法でそれを実行できるようになるためにネットワークをいじる必要があります。

HTH


1

または、sshfsを介してリモートファイルシステムをマウントします

sshfs user@remotehost:/path/on/remote /path/on/local

1

最もエレガントではありませんが、特に単一のzipまたはtarファイルをコピーするわけではなく、ネットワークのオーバーヘッドを減らすのに役立たないので、私の唯一の選択は使用することでしたscp -r

-r

      ディレクトリ全体を再帰的にコピーします。scp ツリートラバーサルで検出されたシンボリックリンクに従うことに注意してください。
ソース:scp(1)

30 GBの圧縮されたtarファイルでディスク領域が不足する問題に直面していました。gunzipはインラインで実行できると考えました。つまり、元のファイルを解凍中に削除しました(そして、Googleの結果を見逃したかもしれません)が、何も見つかりませんでした。

最後に、新しいTARまたはZIPファイルのtar'ingまたはzip圧縮が完了するのを何度も待つのにうんざりしていたので、ついにやった:

  1. 元のサーバー/ PC /ラップトップから、多数のファイル/フォルダーがあるフォルダーに移動します。
  2. scp -r source_folder_name yourname@yourservername:destination_folder_name

その後、ビール、コーヒー、またはポップコーンを手に取り、待ちます。良いことは、ネットワーク接続が「停止」するとscpが再試行することです。完全にダウンしないことを願っています。


わかりました、これは明らかに、1000個のscpコマンドを入力するよりも時間がかかりません。しかし、質問は「ネットワークオーバーヘッド」について尋ねています。ソリューションでは、各ファイルを個別にコピーするよりもネットワークを使用していますか?あなたのソリューションは、すでに投稿されている7つよりも優れていますか?
G-Manは「Reinstate Monica」と言います

スナップ、私の悪い-私は完全にネットワークのオーバーヘッド部分を見逃した-@ G-Manを指摘してくれてありがとう。私は答えを更新しましたが、誰かが私と同じような問題に出くわし、この質問につまずいたとき、それはまだ役に立つかもしれません。
JGlass
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.