linuxでの「scp」の使い方メモです。
scpについて
「scp」は「ssh」を使用してネットワーク越しに、ファイル等をコピーするコマンドです。
注意点
「scp」を使用する際の注意点としては、同名のファイルやディレクトリがコピー先にあった場合、問答無用で上書きしてしまいますので十分に注意して作業を行ってください。
オプション
「scp」を使用するにあたり普段使いそうなオプションについて説明していきます。
オプション | 機能説明 |
---|---|
-i 秘密鍵ファイル | 秘密鍵を使用する場合に使用 |
-l 帯域 | 通信帯域を制限する場合に使用(Kbit/s単位) |
-P ポート番号 | SSHの接続ポート番号が接続先で変更されている場合に使用 |
-p | コピー元データの更新時間やパーミッション(モード)情報を保持させる |
-q |
サイレントモード 実行状況などの詳細状況を表示させない |
-r |
フォルダをコピーする際に使用 ディレクトリ内のデータを再帰的にコピーする |
-C | データを圧縮しコピーする |
-v |
冗長表示モード 詳細な経過情報を表示させる(デバッグ時などに使用) |
その他のオプション
今回は触れませんが、他にも下記のようなオプションもあります。
オプション | 機能説明 |
---|---|
-1 | SSHのプロトコル1を使用 |
-2 | SSHのプロトコル2を使用 |
-3 |
2つのリモートホスト間でコピーする際に、ローカルホストを経由させてコピーを行う 通常は、リモートホスト同士のデータコピーは、リモートホスト間で直接データがコピーされる) |
-4 | IPv4のみを使用する |
-6 | IPv6のみを使用する |
-B |
バッチモード パスワードを問い合わせない(使い方がよくわかりません…) |
-c |
暗号方式 データ転送経路の暗号化を指定する |
-F SSH設定ファイル | SSHの設定ファイルを指定 |
-o | SSHのオプションを使用 |
基本的な使い方
「scp」の基本的な使い方は下記の通りとなります。
※ローカルホストのユーザと、接続先のユーザが同じ名前のユーザ名の場合は、 [接続先ユーザ]@の部分を省略できます。
scp書式
リモートホストからのローカルへコピー
scp [ オプション ] [接続先ユーザ]@ホスト名(IPアドレス):コピー元 コピー先
ローカルからリモートホストへのコピー
scp [ オプション ] コピー元 [接続先ユーザ]@ホスト名(IPアドレス):コピー先
リモートホスト同士
「scp」はリモートホスト同士でのデータコピーも行うことができます。
scp [ オプション ] [接続先ユーザ]@ホスト名(IPアドレス):コピー元 [接続先ユーザ]@ホスト名(IPアドレス):コピー先
※あまり使ったことが無いですが・・・
実行例
リモートホストからのコピー
「192.168.1.130」のホストに「tamohiko」というユーザで接続し、ホームディレクトリにある「10M」というファイルをコピーしてくる例です。
$ scp tamohiko@192.168.1.130:/home/tamohiko/10M ./ tamohiko@192.168.1.130's password: 10M 100% 10MB 10.0MB/s 00:00
リモートホストへのコピー
ローカルホストにある「15M」というファイルを、「192.168.1.130」のホストへ「tamohiko」ユーザで接続し「/home/tamohiko」ディレクトリにコピーする例です。
$ scp 15M tamohiko@192.168.1.130:/home/tamohiko/15M tamohiko@192.168.1.130's password: 15M 100% 15MB 15.0MB/s 00:01
リモートホスト同士のコピー
「192.168.1.130」のホストに「tamohiko」ユーザで接続し、「/home/tamohiko/10M」というファイルを、「192.168.1.150」のホストに「test1」ユーザで接続し「/home/test1」ディレクトリへコピーする例です。
$ scp tamohiko@192.168.1.130:/home/tamohiko/10M test1@192.168.1.150:/home/test1 tamohiko@192.168.1.130's password: test1@192.168.1.150's password: 10M 100% 10MB 10.0MB/s 00:00 Connection to 192.168.1.130 closed.
-r オプション(ディレクトリのコピー)
ディレクトリをコピーする際は「-r」オプションを使います。
書式
scp -r [ユーザ名]@ホスト名(IPアドレス):コピー元 コピー先
使用例
「192.168.1.130」のホストから「/home/tamohiko/data」というディレクトリをコピーする例です。
$ scp -r tamohiko@192.168.1.130:/home/tamohiko/data ./ tamohiko@192.168.1.130's password: 1M 100% 1024KB 1.0MB/s 00:00 5M 100% 5120KB 5.0MB/s 00:00
「/home/tamohiko/data」ディレクトリの中には「1M」と「5M」というファイルがあったので、それらがコピーされていることも実行結果から確認できます。
-p オプション(データ情報保存)
「-p」オプションを使用することで、コピー元ファイルの時刻情報やパーミッションを保持させたままデータをコピーすることが出来ます。
書式
scp -p [ユーザ名]@ホスト名(IPアドレス):コピー元 コピー先
使用例
「-p」オプションの有り無しでの動作について比較してみます。
タイムスタンプ確認
まずはリモートホストにあるコピー元のファイル情報を確認します。
$ ls -l 10M -rwx------ 1 tamohiko tamohiko 10485760 2月 22 23:37 10M
タイムスタンプが「2月 22 23:37」であることが確認できました。
「-p」オプションなしで実行
scp実行
最初に「-p」オプションを指定しないで「scp」を実行してみます。
$ 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」の実行時刻に変更されていることが確認できました。
$ ls -l 10M -rwx------ 1 tamohiko tamohiko 10485760 2月 23 14:46 10M
「-p」オプションを指定して実行
scp実行
次に「-p」オプションを指定して「scp」を実行してみます。
$ scp -p tamohiko@192.168.1.130:/home/tamohiko/10M ./ tamohiko@192.168.1.130's password: 10M 100% 10MB 10.0MB/s 00:00
ファイルの確認
コピーされたファイルを確認すると、タイムスタンプがリモートホストのコピー元ファイルと同時刻であることが確認できました。
$ ls -l 10M -rwx------ 1 tamohiko tamohiko 10485760 2月 22 23:37 10M
-P オプション (ポート番号変更)
リモートホストのSSH待ち受けポートがデフォルトの22番から変更されている場合は、「-P」(Pは大文字)オプションを指定することで接続ポート番号指定することが出来ます。
書式
scp -P [ポート番号] [接続先ユーザ]@ホスト名(IPアドレス):コピー元 コピー先
使用例
SSHの接続ポートが10022番のリモートホスト(192.168.1.130)に「tamohiko」ユーザで接続し、ホームディレクトリにある「20M」というファイルをコピーした際のログです。
$ scp -P 10022 tamohiko@192.168.1.130:/home/tamohiko/20M ./ tamohiko@192.168.1.130's password: 20M 100% 20MB 20.0MB/s 00:00
-i オプション (秘密鍵の使用)
SSH接続に秘密鍵が必要なホストとの間でデータをやり取りする場合、「-i」オプションを使用することで秘密鍵を指定することが出来ます。
書式
scp -i [秘密鍵] [接続先ユーザ]@ホスト名(IPアドレス):コピー元 コピー先
使用例
「192.168.1.150」のリモートホストに秘密鍵(/home/tamohiko/.ssh/id_ecdsa)を使用して接続し、ファイルをコピーした際のログです。
$ scp -i /home/tamohiko/.ssh/id_ecdsa test1@192.168.1.150:/home/test1/20M ./ 20M
※今回検証行った環境の秘密鍵には、パスワード(パスフレーズ)が設定されていないので、「scp」実行時にパスワードを聞かれていません。
-l オプション (帯域制限)
ネットワークの帯域をあまり使いたくない場合などは、「-l」オプションを指定することで、「scp」で使用するネットワークの帯域制限を行うことが出来ます。
指定する帯域の単位は「Kbit/s」になります。
書式
scp -l [帯域(Kbit/s)] [接続先ユーザ]@ホスト名(IPアドレス):コピー元 コピー先
使用例
サイズが100Mのファイルを帯域制限ありと無しでコピーし、動作を比較してみました。
制限なしの場合
LAN上のリモートホストからのコピーだったので、「100.0MB/s」のスピードがでて一瞬でコピーが完了しました。
$ scp tamohiko@192.168.1.130:/home/tamohiko/100M ./ tamohiko@192.168.1.130's password: 100M 100% 100MB 100.0MB/s 00:00
帯域制限ありの場合
「-l」オプションを指定し帯域を10000 Kbit/s (10MB/s)(1.25MB/s)に制限します。
$ scp -l 10000 tamohiko@192.168.1.130:/home/tamohiko/10 0M ./
tamohiko@192.168.1.130's password:
100M 10% 10MB 9.0MB/s 00:09 ETA
9.0MB/s までしか転送速度が出ていないことが確認でき、帯域制限が掛かっていることが確認できます。
※2021.08.30 帯域制限の変換計算を間違っていたので訂正しました。
CentOS7での検証結果 2021.08.30
CentOS7で再度検証を行った結果、下記のように転送速度は最初9.8MB/sと表示されていましたが、徐々に帯域制限した値になっていきました。
$ scp -l 10000 ./100MB tamohiko@192.168.1.101:/home/tamohiko tamohiko@192.168.1.101's password: 100MB 9% 10MB 9.8MB/s 00:09 ETA 100MB 9% 10MB 8.8MB/s 00:10 ETA 100MB 9% 10MB 7.1MB/s 00:12 ETA 100MB 14% 15MB 4.7MB/s 00:18 ETA 100MB 18% 18MB 2.8MB/s 00:28 ETA 100MB 23% 23MB 2.3MB/s 00:33 ETA 100MB 32% 32MB 1.7MB/s 00:39 ETA 100MB 38% 38MB 1.5MB/s 00:40 ETA 100MB 47% 48MB 1.3MB/s 00:39 ETA 100MB 98% 99MB 1.2MB/s 00:00 ETA 100MB 100% 100MB 1.2MB/s 01:21 100% 100MB 1.2MB/s 01:21
Ubuntu20.04での検証結果 2021.08.30
ちなみにUbuntu20.04で検証を行ったところ、最初から帯域制限を行った値で表示されていました。
$ scp -l 10000 ./100MB tamohiko@192.168.1.102:/home/tamohiko tamohiko@192.168.1.102's password: 100MB 1% 1248KB 1.2MB/s 01:21 ETA 100MB 2% 2480KB 1.2MB/s 01:20 ETA 100MB 3% 3712KB 1.2MB/s 01:19 ETA 100MB 4% 4944KB 1.2MB/s 01:18 ETA 100MB 6% 6160KB 1.2MB/s 01:17 ETA 100MB 14% 14MB 1.2MB/s 01:11 ETA 100MB 100% 100MB 1.2MB/s 01:23
CentOS7とUbuntu20.04どちらの場合も転送にかかった時間はほぼ同じだったので、帯域制限自体は同じように行われているのでしょうが、転送速度や転送完了までの時間を計算する方法が異なっているではないかと思われます。
-C オプション (データ圧縮)
「-C」(Cは大文字)オプションを指定することで、データをコピーする際にデータを圧縮し転送することができます。
インターネット上のホストからデータをコピーする場合など、通信経路の帯域が少ない時に設定すると転送時間の短縮が期待できます。
書式
scp -C [接続先ユーザ]@ホスト名(IPアドレス):コピー元 コピー先
使用例
インターネット上にあるサーバから、ファイルサイズが100Mのデータを圧縮有と無しの両方で「scp」でコピーした際の比較です。
圧縮無しの場合
データ転送速度は「3.0MB/s」出ていて、ファイルのコピーが完了するまでに33秒かかりました。
$ scp tamohiko@xxx.xxx.xxx.xxx:/home/tamohiko/100M ./ tamohiko@xxx.xxx.xxx.xxx's password: 100M 100% 100MB 3.0MB/s 00:33
圧縮有りの場合
データ転送速度は「50MB/s」出ていて、ファイルのコピーが完了するまでに2秒かかりました。
$ scp -C tamohiko@xxx.xxx.xxx.xxx:/home/tamohiko/100M ./ tamohiko@xxx.xxx.xxx.xxx's password: 100M 100% 100MB 50.0MB/s 00:02
コピー対象のデータにより圧縮が効きやすい、効きづらいの違いはあると思いますが、インターネット上のホストからのデータコピーは「-C」オプションを付けて圧縮をかけたほうがコピーの時間が圧倒的に短縮されました。
-q オプション (サイレントモード)
「-q」オプションを付けることで、データ転送状況の表示を行わなくなります。
書式
scp -q [接続先ユーザ]@ホスト名(IPアドレス):コピー元 コピー先
使用例
「-q」オプションを付ける、付けないでの動作を比較してみました。
「-q」を指定しない場合
「-q」オプションを指定しない場合は、データコピーの状況が表示されています。
$ scp tamohiko@192.168.1.130:/home/tamohiko/20M ./ tamohiko@192.168.1.130's password: 20M 100% 20MB 20.0MB/s 00:00 <--コピー状況が表示されています
「-q」を指定した場合
「-q」を指定することで、データコピーの状況が表示されなくなっています。
$ scp -q tamohiko@192.168.1.130:/home/tamohiko/20M ./ tamohiko@192.168.1.130's password:
-v オプション (冗長表示)
「-v」オプションをを付けることで、「scp」実行時の詳細な情報が表示されるようになります。
そのため、「scp」の動作に問題が発生した場合などは、このオプションを使用することで原因を調査することが出来ます。
書式
scp -v [接続先ユーザ]@ホスト名(IPアドレス):コピー元 コピー先
使用例
「-v」オプションを使用すると、非常に多くの情報が表示されるようになります。
$ scp -v tamohiko@192.168.1.130:/home/tamohiko/20M ./ Executing: program /usr/bin/ssh host 192.168.1.130, user tamohiko, command scp -v -f /home/tamohiko/20M OpenSSH_6.6.1, OpenSSL 1.0.1e-fips 11 Feb 2013 debug1: Reading configuration data /etc/ssh/ssh_config debug1: /etc/ssh/ssh_config line 56: Applying options for * debug1: Connecting to 192.168.1.130 [192.168.1.130] port 22. debug1: Connection established. ##### 省略 ##### debug1: Sending environment. debug1: Sending env LANG = ja_JP.UTF-8 debug1: Sending command: scp -v -f /home/tamohiko/20M Sending file modes: C0664 20971520 20M Sink: C0664 20971520 20M 20M 100% 20MB 20.0MB/s 00:00 debug1: client_input_channel_req: channel 0 rtype exit-status reply 0 debug1: client_input_channel_req: channel 0 rtype eow@openssh.com reply 0 debug1: channel 0: free: client-session, nchannels 1 debug1: fd 0 clearing O_NONBLOCK debug1: fd 1 clearing O_NONBLOCK Transferred: sent 9052, received 20994620 bytes, in 0.2 seconds Bytes per second: sent 51946.9, received 120482240.1 debug1: Exit status 0
※表示されるログが多いので、途中のログを省略しています。
設定ファイル(~/.ssh/config)を使用した方法
ここまでは、「scp」実行時のオプションについて説明してきましたが、ここからはそれ以外ことについて説明していきます。
「scp」を実行するユーザで「~/.ssh/config」というファイルを作成すると、接続先ホストの接続ポートや秘密鍵の場所等をホストごとに設定することができて、いちいちオプションで指定する必要が無くなります。
ちなみに、この「config」ファイルは別に「scp」専用の設定ファイルという事ではなく、「SSH」接続管理用の設定ファイルとなります。
書式(必要最低限)
設定できる項目はまだまだありますが、すべてを説明すると非常に項目が多くなってしまうのでとりあえず普段使用しそうな項目のみです。
Host [設定名] Hostname [接続先ホスト名 or IPアドレス] Port [接続ポート番号](必要があれば) IdentityFile [秘密鍵](必要があれば) User [接続ユーザ名] (必要があれば)
複数ホスト設定を行う場合は、「Host」から
man ssh_configでその他の項目については確認できます・・・
configの作成
「config」ファイルは、ユーザのホームディレクトリ上にある「.ssh」フォルダ内に作成する必要があります。
$ cd ~/.ssh $ vi config
設定内容
今回は「host_A」と「host_B」という設定名で、2台のリモートサーバに接続する際の設定を作成しました。
Host host_A Hostname 192.168.1.130 Port 10022 IdentityFile ~/.ssh/id_ecdsa User tamohiko Host host_B Hostname 192.168.1.150
パーミッション設定
「config」ファイルに「グループ」や「他のユーザ」から書き込み権限があると、エラーとなり「scp」が実行できません。
そのため、パーミッションを「600」に変更します。
$ chmod 600 config
Bad owner or permissions
所有者以外のパーミッションに書き込み権限がある場合の動作例です。
グループに対して書き込み権限を与えてみました。
-rw-rw-r-- 1 tamohiko tamohiko 126 2月 24 02:44 config
scp 実行
この状態で、「scp」を実行すろと「Bad owner or permissions」と表示されて「scp」を行うことが出来ないことが確認できました。
$ scp host_a:/home/tamohiko/10M ./ Bad owner or permissions on /home/tamohiko/.ssh/config
使用方法
「config」ファイルに設定した「Host」部分を指定することで、その情報を読み込むことが出来ます。
使用例
「config」ファイルに設定した「host_A」からデータをコピーする場合は、下記のように「Host」部分で設定した設定名を指定して行います。
$ scp host_A:/home/tamohiko/100M ./ tamohiko@192.168.1.130's password: 100M 100% 100MB 100.0MB/s 00:01
「host_A」と指定するだけで、「config」ファイルに設定したホストの「IPアドレス」「接続ポート番号」「秘密鍵」「ユーザ名」といった情報を読み込んで接続してくれます。
オプション指定の優先順位
「scp」を実行する際に、「config」ファイルに設定されているものと違うオプションをしてした場合はどうなるでしょう?
この場合は、コマンド実行時に指定したオプションが有効となります。
「scp」実行時に反映されるオプションには、優先順位があり順番は下記の通りとなります。
- コマンド実行時に指定したオプション
- ユーザ毎のconfigで設定された値(~/.ssh/config)
- システムでの設定値(/etc/ssh/ssh_config)
エラーメッセージ
「scp」を使用した際に遭遇したエラーについてメモしておきます。
Permission denied
コピーするディレクトリ・ファイルに書き込み権限がない場合表示されるので、ファイルの所有者やパーミッションの確認をしましょう。
not a regular file
ディレクトリをコピーする際に「-r」オプションを使用しない場合に表示されます。
$ scp tamohiko@192.168.1.130:/home/tamohiko/data ./ tamohiko@192.168.1.130's password: scp: /home/tamohiko/data: not a regular file
ディレクトリをコピーする際には「-r」オプションの指定を忘れずに
コメント
「7 -l オプション (帯域制限)」の「7.2 使用例」に
「帯域を10000 Kbit/s (10MB/s)に制限します。」
と書かれてますが、1Byte = 8bit なので、
10000Kbit/s = 10000/8KB/s = 1250KB/s ≒ 1.3MB/s
ではないでしょうか?
実測結果の「9.0MB/s」とは合いませんが
jbpb0 さん
ご指摘ありがとうございます。
jbpb0さんのおっしゃるとおり約1.3MB/sとなりますね。
当時は10Mbit/sと勘違いして記事を書いていたのだと思いますので、訂正させていただきます。
> 実測結果の「9.0MB/s」とは合いませんが
CentOS7の環境で再度検証してみたところ、転送直後は9.8MB/sぐらいで表示されていて、その後少しづつ帯域制限した速度と同等の表示になっていきました。
この記事を書いた時には、たぶん最初の方の表示をコピーしていたので実測結果が異なって表示されていたのだと思います。
ちなみにUbuntu20.04の場合は転送直後から1.2MB/sと表示されていました。
こちらの結果についても、あわせて訂正させていただきます。
ありがとうございました。
scpでオプション-Bを使った使用例を教えていただけませんか?
white89さん
コメントありがとうございます。
tamohikoです。
scpのオプション「-B」使用方法について調べてみました。
このオプションを使用するには、前提条件として事前にSSHに鍵認証方式を導入しておく必要があり、その際作成する鍵にはパスワードを設定しないようにして下さい。
パスワードが設定されていない鍵を使用してSSH接続が可能なことを確認後、下記の書式でscpコマンドを実行してみてください。
$ scp -B ファイル名 ユーザ名@サーバIP:ディレクトリ
または、
$ scp -B -i 秘密鍵 ファイル名 ユーザ名@サーバIP:ディレクトリ
※CentOSでの鍵作成方法
以上、よろしくお願いします。