tarコマンドでサーバから大量のファイルを高速でダウンロードする

はじめに

リモートサーバにある大量のファイルをまとめてローカルPCにダウンロードしたかった時の話。

少数のファイルならFTPソフトでダウンロードするのがお手軽だけど、大量のファイルだと時間がかかるのと、途中で止まってしまうこともあったので、他に良い方法がないか調べてみた。

前提

  • ターミナルでコマンド操作ができる
  • サーバにSSH接続ができる

具体例としてXSERVERの場合のコマンドも記載してあります。

scpとtarコマンド

調べてみると、ターミナル上で簡単なコマンドを実行する事でダウンロードできるようです。転送コマンドとして最初にscpコマンドを試したが、複数のファイルを一個ずつ転送するので、速度的にはとても遅かった。

大量のファイルを高速に転送するには、tarコマンドで圧縮してから転送するといいようです。

高速転送コマンド

最終的なコマンドは以下のようになりました。

$ ssh [username]@[remote-hosts] 'tar -C [~/path] -zcf - [directory]' | tar zxf -

オプションや書き方が複雑で何をやっているかよくわかりませんが、簡単にいうと、sshでリモートホストに接続してtar圧縮コマンドを実行後、パイプでつないだtar解凍コマンドでローカルに保存しています。

解説

せっかくなので、scpコマンドから順に説明していきます。

scpコマンド

scpコマンドは、cpコマンド(ローカル内ファイルコピー)をリモートホスト間でSSH接続を利用して行うためのコマンドです。

書式

scp [オプション] コピー元 コピー先

リモート → ローカル

ローカルの保存先フォルダ内で以下のコマンドを実行。

$ scp [username]@[remote-hosts]:[~/filename] ./

コピー先の./はカレントディレクトリを意味しています。.だけでもいいです。

XSERVERの場合
$ scp -P 10022 [username]@[svxxxx.xserver.jp]:[~/domain.com/public_html/filename] ./

XSERVERのSSHポートは22ではなく10022なので、-Pオプションでポートを指定する必要があります。指定しないとデフォルトの22が指定されます。

ディレクトリごと転送する場合
$ scp -r -P 10022 [username]@[svxxxx.xserver.jp]:[~/domain.com/public_html/directory] ./

-rオプションで対象のディレクトリ内のすべてのファイルを対象にできます。

tarコマンド

tarコマンドは、複数のファイルを1まとまり(アーカイブ)にするコマンドです。オプションで圧縮したり解凍したりすることもできます。

書式

tar [オプション] 保存ファイル名 対象ファイル

tarコマンドについての詳細は省略しまして、本題の高速転送コマンドをみていきます。

圧縮と転送

事前にサーバ側でtarコマンドで圧縮してから、ローカルでscpコマンドを実行しても良いですが、以下のように書くと圧縮と転送が同時にできます。

$ ssh [username]@[remote-hosts] 'tar zcf - -C [~/path] [directory]' | tar zxf -

pathdirectoryの間に半角スペースがあるので注意です。path-Cオプションの値です。目的のディレクトリまでのパスを書きます。cd(階層移動)するイメージです。

以下のように書くとわかりやすいかもです。

$ ssh [username]@[remote-hosts] 'tar -C [~/path] -zcf - [directory]' | tar zxf -

元々tarコマンドのオプションは-ハイフンが省略できますが、この場合zcfオプションの前に-ハイフンが必要になります。

もう一つ単独の-ハイフンがありますが、これは標準出力を意味しています。保存ファイル名を書く代わりに-ハイフンを書くとファイルへ出力せずに標準出力します。これをパイプ後に解凍しています。

オプション補足

zcf gzip圧縮(圧縮しない場合はcf(複数ファイルをまとめる)だけでOK)
zxf gzip解凍(圧縮していない場合はxfだけでOK)
-C ディレクトリ指定(指定しないと目的のディレクトリまでの階層構造をそのままアーカイブします)
他にもいくつかオプションがありますが、詳細はここでは省略します。

XSERVERの場合
$ ssh -p 10022 [username]@[svxxxx.xserver.jp] 'tar -C [~/domain.com/public_html/path] -zcf - [directory]' | tar zxf -

scpコマンドの場合と同様にポート指定が必須です。

まとめ

tarコマンドで圧縮と転送を同時にできる事がわかりました。scpコマンドと比べて圧倒的に速いです。圧縮する場合はサーバのリソースが消費されるので、あまり大量のファイルの場合は圧縮しない方がいいかもです。

転送元と転送先を入れ替えれば、ローカルからリモートホストへファイル転送することもできます。ポイントは標準出力のところだと思いますがイマイチ理解が難しいです。。。Linuxコマンドは難しいですね。もっとLinuxについて勉強が必要です😅