Ubuntuでscpを使ってネットワーク越しにデータをコピーする方法です。
scpとは
「scp」は「SSH」で暗号化された通信経路を使用して、ネットワーク越しにファイル等をコピーするコマンドです。
「SSH」を使ってデータの転送を行う方法として「sftp」もありますが、コピーするデータの数が少ないのであれば「scp」の方が対話形式ではないため簡単にデータのコピーを行うことができます。
「scp」でデータをコピーする際の注意点
「scp」を使用する際の注意点としては、同名のファイルやディレクトリがコピー先にあった場合、問答無用で上書きしてしまいますので十分に注意して作業を行ってください。
「scp」の使用方法
「scp」の基本的な使い方は「cp」コマンドと同じで、下記のようにデータのコピー元とコピー先を指定して使用します。
リモートホストからデータをコピー
ネットワーク越しのリモートホストからデータをコピーするには、下記の書式でデータのコピー元とコピー先を指定します。
scp ユーザ@リモートホスト:コピー元データ ロカールホストのコピー先ディレクトリ
リモートホストへの接続ユーザ部分の指定を省略すると、ローカルホストにログインしているユーザが指定されます。
実行例
リモートホスト(192.168.1.130)から「/home/tamohiko/10M」というデータを、ローカルホストの「./」(現在のディレクトリ)にコピーしてみます。
ログインパスワードの入力を求められるので、SSHで接続する際のパスワードを入力してあげてください。
$ scp tamohiko@192.168.1.130:/home/tamohiko/10M ./ tamohiko@192.168.1.130's password: 10M 100% 10MB 10.0MB/s 00:00
ローカルホストからデータをコピー
ローカルホストにあるデータをリモートホストにコピーする場合は、下記の書式でデータのコピー元とコピー先を指定します。
scp ローカルホストのデータパス ユーザ@リモートホスト:コピー先ディレクトリ
実行例
ロカールホストの「10M」というファイルを、リモートホスト(192.168.1.130)の「/home/tamohiko/work」というディレクトリにコピーしてみます。
$ scp ./10M tamohiko@192.168.1.130:/home/tamohiko/work/ 10M 100% 10MB 4.9MB/s 00:02
秘密鍵や接続ポート番号を指定する場合
SSHの接続に秘密鍵が必要な場合や、接続するポート番号を22番ポートから変更している際には、以下のオプションを使用します。
- -i 秘密鍵
- -P ポート番号
リモートホストからローカルホストへデータをコピーする場合は以下の書式となります。
$ scp -i 秘密鍵 -P ポート番号 ユーザ@リモートホスト:コピー元データ ロカールホストのディレクトリ
ローカルホストからリモートホストへデータをコピーする場合は以下の書式となります。
$ scp -i 秘密鍵 -P ポート番号 ロカールホストのデータ ユーザ@リモートホスト:コピー先ディレクトリ
実行例
「-i」と「-P」オプションの使用例として、以下のリモートホストからローカルホストへのデータコピーと、ローカルホストからリモートホストへのデータコピーを実行します。
- リモートホストアドレス: 192.168.1.1
- 接続ユーザ: tamohiko
- 秘密鍵: ~/.ssh/id_ed25519
- SSH接続ポート: 10022
リモートホストからロカルホストへコピー
リモートホストの「10MB_DATA」というファイルを、ローカルホストの「./」(現在のディレクトリ)にコピーします。
秘密鍵にパスフレーズを設定している場合は入力を求められます。
$ scp -i ~/.ssh/id_ed25519 -P 10022 tamohiko@192.168.1.1:10MB_DATA ./ Enter passphrase for key '/home/tamohiko/.ssh/id_ed25519': 10MB_DATA 100% 10MB 99.1MB/s 00:00
ローカルホストからリモートホストへコピー
ローカルホストの「10MB_DATA」というファイルを、リモートホストの「/home/tamohiko/work/」ディレクトリにコピーします。
$ scp -i ~/.ssh/id_ed25519 -P 10022 ./10MB_DATA tamohiko@192.168.1.1:/home/tamohiko/work/ Enter passphrase for key '/home/tamohiko/.ssh/id_ed25519': 10MB_DATA 100% 10MB 41.6MB/s 00:00
「~/.ssh/config」を使って簡単に「scp」を実行しよう
「~/.ssh/config」には、SSHでリモートホストに接続するための情報を設定しておくことが出来ます。
「scp」を実行するユーザで「~/.ssh/config」ファイルに、接続先ホストの接続ポートや秘密鍵の場所等を設定しておくことで、とても簡単に「scp」を実行することが出来るようになります。
「~/.ssh/config」の作成
「~/.ssh」ディレクトリが存在していない場合はディレクトリを作成します。
$ mkdir ~/.ssh $ chmod 700 ~/.ssh
「~/.ssh/config」にSSH接続用の設定を行います。
$ vi ~/.ssh/config
基本的な設定内容は下記の通りです。
「IdentityFile 秘密鍵」と「IdentitiesOnly yes」の項目は、SSH接続に秘密鍵が必要な場合に設定します。
Host 設定名(サーバ名等を記述) HostName 接続先サーバアドレス User 接続ユーザ Port ポート番号 TCPKeepAlive yes ServerAliveInterval 60 IdentityFile 秘密鍵 # 秘密鍵を指定 IdentitiesOnly yes # 鍵認証方式の場合 yes
下記情報のリモートホスト設定例です。
- リモートホストアドレス: 192.168.1.1
- 接続ユーザ: tamohiko
- 接続ポート: 10022
- 秘密鍵: ~/.ssh/id_ed25519
設定名は「host_a」としています。
Host host_a HostName 192.168.1.1 User tamohiko Port 10022 TCPKeepAlive yes ServerAliveInterval 60 IdentityFile ~/.ssh/id_ed25519 IdentitiesOnly yes
動作検証
設定名に指定した名前でSSH接続が出来るか確認します。
$ ssh host_a
秘密鍵にパスフレーズが設定されている場合は入力を求められるので、設定されているパスフレーズを入力してください。
これでSSH接続できれば設定は完了です。
「~/.ssh/config」についてより詳しい説明を下記ページで行っていますので、よければ参考にしてみてください。

scp実行例
「~/.ssh/config」に設定を行うと、リモートホストを「host_a」と記述するだけになるので、入力する文字数がかなり少くなくなるため、下記のようにとても簡単に「scp」コマンドを実行することが出来るようになります。
$ scp ./10MB_DATA host_a:/home/tamohiko/work/
オプションの説明
「scp」を使用するにあたり、普段使いそうなオプションを抜粋して説明していきます。
オプション | 説明 |
---|---|
-p | コピー元データの更新時間、パーミッション情報を保持させる |
-q |
サイレントモード 実行状況などの詳細状況を表示させない |
-r |
フォルダをコピーする際に使用 ディレクトリ内のデータを再帰的にコピーする |
-v |
冗長表示モード 詳細な経過情報を表示させる(デバッグ時などに使用) |
-C | データを圧縮しコピーする |
-p 更新時間やパーミッション情報を保持
「-p」オプションと使うと、コピー元ファイルの時刻情報やパーミッションを保持させたままデータをコピーすることが出来ます。
ローカルホストにある「10MB_DATA」というファイルを使って「-p」オプションの有りと無しで、コピー後のファイルの情報を比べてみます。
$ ls -l 10MB_DATA -rw-rw-r-- 1 tamohiko tamohiko 10485760 2月 7 10:49 10MB_DATA
「-p」 オプションなし
「-p」オプションを指定せずに「scp」を行います。
$ scp ./10MB_DATA host_a:/home/tamohiko/work 10MB_DATA 100% 10MB 3.1MB/s 00:03
リモートホストでコピーしてきたファイルの情報を確認すると、ファイルのタイムスタンプが「scp」してきた時間に変更されていることが確認できました。
$ ls -l 10MB_DATA -rw-rw-r-- 1 tamohiko tamohiko 10485760 Feb 8 22:33 10MB_DATA
「-p」 オプションあり
次に「-p」オプションを指定して「scp」を行います。
$ scp -p ./10MB_DATA host_a:/home/tamohiko/work 10MB_DATA 100% 10MB 2.7MB/s 00:03
リモートホストでコピーしてきたファイルの情報を確認すると、ファイルのタイムスタンプはローカルホストにあるファイルと同じであることが確認できました。
$ ls -l 10MB_DATA -rw-rw-r-- 1 tamohiko tamohiko 10485760 Feb 7 10:49 10MB_DATA
-q サイレントモード
「-q」オプションを使用すると、データのコピー状況についての情報が表示されなくなります。
$ scp -q ./10MB_DATA host_a:/home/tamohiko/work
私は、シェルスクリプトで「scp」を実行する場合にこちらのオプションを使うことが多いです。
-r ディレクトリをコピー
「scp」でディレクトリをコピーする場合は「-r」オプションを使用します。
「-r」オプションを使用せずにディレクトリをコピーしようとすると、「not a regular file」とメッセージが表示されて失敗してしまいます。
$ scp ./test_dir/ host_a: scp: local "./test_dir" is not a regular file scp: failed to upload file ./test_dir to .
「-r」オプションを使用すると、以下のようにディレクトリのコピーを行うことが出来ます。
$ scp -r ./test_dir/ host_a: 10MB_DATA_2 100% 10MB 4.3MB/s 00:02
-v 詳細な経過情報を表示
「-v」オプションを使用すると「scp」を実行する際の詳細情報を表示してくれます。
「scp」の動作に問題が発生した場合などは、このオプションを使用することで原因を調査することが出来ます。
$ scp -v ./10MB_DATA host_a:/home/tamohiko/work Executing: program /usr/bin/ssh host host_a, user (unspecified), command sftp OpenSSH_9.6p1 Ubuntu-3ubuntu13.5, OpenSSL 3.0.13 30 Jan 2024 debug1: Reading configuration data /home/tamohiko/.ssh/config ### 中略 ### debug1: pledge: fork 10MB_DATA 100% 10MB 3.1MB/s 00:03 scp: debug1: truncating at 10485760 debug1: client_input_channel_req: channel 0 rtype exit-status reply 0 debug1: channel 0: free: client-session, nchannels 1 Transferred: sent 10497228, received 8352 bytes, in 4.3 seconds Bytes per second: sent 2424109.1, received 1928.7 debug1: Exit status 0
-C データを圧縮してコピー
「-C」オプションを使用すると、データを圧縮してデータのコピーを行ってくれます。
圧縮が効くデータの場合はデータのコピーに掛かる時間がが短くなることが期待できますが、すでに圧縮済みのデータであったり圧縮があまり効かないデータの場合は、コピー時間が短くなることにはそれほど期待はできません。
テスト用に100MBのデータを作成して「-C」オプションの有り・無しでコピー時間の比較をしてみます。
$ dd if=/dev/zero of=100MB_ZERO_DATA bs=1M count=100 100+0 records in 100+0 records out 104857600 bytes (105 MB, 100 MiB) copied, 0.102961 s, 1.0 GB/s
ちなみに、今回作成したデータは「/dev/zero」で作成しているので、「gzip」で圧縮してみると下記のように圧縮がかなり効きます。
$ gzip -c 100MB_ZERO_DATA > 100MB_ZERO_DATA.gz $ ls -lh 100MB_ZERO_DATA* -rw-rw-r-- 1 tamohiko tamohiko 100M 2月 9 22:52 100MB_ZERO_DATA -rw-rw-r-- 1 tamohiko tamohiko 100K 2月 10 10:41 100MB_ZERO_DATA.gz
まずは「-C」オプションを使用せずに「scp」でデータのコピーを行ったところ、コピーに掛かった時間は約20秒という結果になりました。
$ scp 100MB_ZERO_DATA host_a:work/ 100MB_ZERO_DATA 100% 100MB 4.9MB/s 00:20
次に「-C」オプションを使用して「scp」を実行してみたところ、コピーにかかった時間は約2秒という結果になり、かなりコピーに掛かる時間が短縮されました。
$ scp -C 100MB_ZERO_DATA host_a:work/ 100MB_ZERO_DATA 100% 100MB 45.6MB/s 00:02
圧縮済みデータでの比較
すでに圧縮されているデータを使って、「-C」オプションの有無によってどのくらいコピー時間が変わるかの比較をしてみます。
テスト用のデータとして、以下の圧縮済みファイルを用意しました。
$ ls -lh vpslife.tar.gz -rw-rw-r-- 1 tamohiko tamohiko 90M 2月 10 10:01 vpslife.tar.gz
まずは、「-C」オプション無しで「scp」を実行すると、コピーに掛かった時間は約17秒となっています。
$ scp vpslife.tar.gz host_a:work/ vpslife.tar.gz 100% 89MB 5.2MB/s 00:17
次に「-C」オプションを使用して「scp」を実行してみたところ、コピーに掛かった時間は約17秒という結果になり、「-C」オプション無しの場合とほぼ同じ結果となりました。
$ scp -C vpslife.tar.gz host_a:work/ vpslife.tar.gz 100% 89MB 5.3MB/s 00:17
すでに圧縮されているデータを再圧縮したとしても、基本はもう圧縮できないということですね。
コメント