LoginSignup
92
77

More than 5 years have passed since last update.

sshだけでファイル・ディレクトリ転送(scp, sftpなし)

Posted at

リモートホストとの間でファイルやディレクトリを転送(送信・受信)したいんだけど、何らかの事情でscpやsftpが使えない(or 使いたくない)からsshだけでなんとかしたい、という時の方法。

まずは結論から

送信

ローカルホストにあるファイル source_dir/source_file をリモートホストの destination_dir に転送するには:

tar czf - -C source_dir source_file | ssh user@remote-host 'tar zxvf - -C destination_dir'

とします。source_file はファイルでもディレクトリでも大丈夫です(ディレクトリなら再帰的に転送されます)。

受信

リモートホストにあるファイル source_dir/source_file をローカルの destination_dir に転送するには:

ssh user@remote-host 'tar czf - -C source_dir source_file' | tar zxvf - -C destination_dir

とします。source_file はファイルでもディレクトリでも大丈夫です(ディレクトリなら再帰的に転送されます)。

解説

ssh コマンドはホスト名の後に引数を与えると、通常の動作と異なり、リモートホスト上でその引数をコマンドとして実行して終了します。
その際、ローカルホストとの間でパイプをつなげることができます。

つまり、ローカルホストのコマンドの標準出力をリモートホストのコマンドの標準入力で受け取ったり、
リモートホストのコマンドの標準出力をローカルホストのコマンドの標準入力で受け取ったりできます。

さて、あるディレクトリ以下のファイルを再帰的にコピーするのに tar を利用する方法があります。
使用頻度は少ないものの、小さいファイルが大量にある場合には cp -r を使うより速かったりします。こんな具合ですね。

tar cf - -C source_dir source_file | tar xvf - -C destination_dir

アーカイブを生成して標準出力に書き出し、標準入力で受け取って別ディレクトリで展開しています。

そう、結論で書いたのは、この方法をリモートホストとの間でやっているだけです。
ついでに、ネットワークを経由しますので tar コマンドにgzip圧縮のオプション z を加えています。

ちなみに、パイプで繋げられるなら tar じゃなくても大丈夫じゃないか?と思われた方、その通りです。
例えば、単一のファイルなら cat でも転送を実現できます。送信なら

cat source_dir/source_file | ssh user@remote-host 'cat > destination_dir/destination_file'

ですね。ネットワーク帯域の消費を節約するためgzip圧縮したいなら、

gzip -c source_dir/source_file | ssh user@remote-host 'gunzip > destination_dir/destination_file'

としてもいいでしょう。

他にもいろいろ応用が効くと思います。tarのオプションを工夫すれば特定ファイルの除外なども可能ですね。

参考

92
77
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
92
77