scpコマンド:使い方とオプション、フォルダーのコピーとポート指定
SSHで接続するサーバーとファイルをやり取りするときに使うコピーツールがscpです。scpコマンドでファイルを送るときは、cpと同じようにコピー元を先に、コピー先を後に書きます。AlmaLinux 9サーバーからDebian 12サーバーへファイルとフォルダーを送り、受け取った結果、転送はSFTPプロトコルで行われ、20MBのファイル1つが1秒以内に届きました。
以下の出力はすべて、送信側のrootアカウントでOpenSSH 9.9のscpを実行した結果そのままです。サーバーのアドレスとアカウント名だけを例の値に置き換えました。
1️⃣ scpの使い方とリモートパス
リモートサーバー側のパスの前には[アカウント@サーバーアドレス:]を付けます。コロンのないパスはコマンドを実行したサーバー内のパスとして認識されるため、コロンが付いている側によって送信か受信かが決まります。
今のフォルダーのreport.txtを、リモートサーバーのホームの下にあるscp-testフォルダーへ送ります。
scp report.txt user@203.0.113.10:~/scp-test/report.txt 100% 14 5.1KB/s 00:00転送が終わると、ファイル名と進捗、サイズ、速度、所要時間が1行で表示されます。この進捗表示はターミナルで実行したときだけ現れます。そのため、出力をファイルにリダイレクトして実行すると、ファイルには何も残りません。
受信するときは、リモートパスを前に、保存先のローカルパスを後に書きます。
scp user@203.0.113.10:~/scp-test/report.txt ./downloads/report.txt 100% 14 2.7KB/s 00:00コピー先のパスをフォルダーではなくファイル名で終えると、その名前で保存されます。以下のコマンドで送った後、受信側のフォルダーにはreport.txtがreport-1028.txtという名前で残っていました。
scp report.txt user@203.0.113.10:~/scp-test/report-1028.txtreport.txt 100% 14 4.6KB/s 00:00🔲 scpコマンドシミュレーター
以下のシミュレーターで、送信と受信、フォルダーコピーのコマンドを実際に入力し、オプションごとの出力を確認できます。
2️⃣ scpコマンドのオプション
オプションはscpのすぐ後、コピー元の前に書きます。ポートを指定する-Pは大文字で、小文字の-pは時刻と権限を保持するオプションなので、大文字と小文字を間違えると別の動作になります。
-lは転送速度の上限をKbit/s単位で指定します。オプションなしで20MBのファイルを送ったときは、1秒以内に転送が終わりました。
scp backup.tar.gz user@203.0.113.10:~/scp-test/backup.tar.gz 100% 20MB 53.6MB/s 00:00-l 8000は毎秒約1,000KBに相当します。同じファイルを-l 8000で送ってみると、進捗表示の速度は996.5KB/sとなり、転送には20秒かかりました。
scp -l 8000 backup.tar.gz user@203.0.113.10:~/scp-test/backup-l.tar.gzbackup.tar.gz 100% 20MB 996.5KB/s 00:20-CはSSH接続でデータをgzipと同じ方式で圧縮します。同じ文章を繰り返した19MBのログファイルを3回ずつ送った結果、このサーバー2台の間では-Cを付けた側が少し遅くなりました。
| コマンド | ファイル | 実行時間 | 進捗表示の速度 |
|---|---|---|---|
| scp backup.tar.gz | 20MB | 0.68秒 | 53.6MB/s |
| scp -l 8000 backup.tar.gz | 20MB | 20.82秒 | 996.5KB/s |
| scp access.log(3回) | 19MB | 0.79~0.89秒 | — |
| scp -C access.log(3回) | 19MB | 0.84~0.97秒 | — |
実行時間は、コマンドを開始して接続し、転送を終えるまでの時間です。sshのマニュアルでも、圧縮は低速な回線で効果があり、高速なネットワークでは転送を遅くすると説明しています。
-vは接続から転送までの過程をdebug1の行で出力するため、接続できないときや認証で止まるときに原因を探すのに使います。出力が長いので、grepで認証と転送の行だけを選びました。
scp -v report.txt user@203.0.113.10:~/scp-test/ 2>&1 | grep -E 'Authenticated|Sending|Transferred'Authenticated to 203.0.113.10 ([203.0.113.10]:22) using "publickey".
debug1: Sending subsystem: sftp
Transferred: sent 2536, received 3248 bytes, in 0.1 seconds[Sending subsystem: sftp]の行は、scpがSFTPプロトコルでファイルを送ったという意味です。OpenSSH 9.0からscpはSFTPを既定で使います。-Oを付けると古いSCPプロトコルで転送し、同じ場所に[Sending command: scp -v -t]が表示されます。
scp -O -v report.txt user@203.0.113.10:~/scp-test/ 2>&1 | grep -E 'Authenticated|Sending|Transferred'Authenticated to 203.0.113.10 ([203.0.113.10]:22) using "publickey".
debug1: Sending command: scp -v -t ~/scp-test/
Sending file modes: C0600 14 report.txt
Transferred: sent 2328, received 3036 bytes, in 0.1 seconds📌 主なオプション: この記事で実行した結果
| オプション | 作業 | この記事で確認した結果 | |
|---|---|---|---|
| -P | SSH接続ポートを指定 | ポート22はreport.txtの転送完了、開いていないポート2222は[Connection timed out]で終了 | |
| -i | 公開鍵認証に使う秘密鍵ファイルを指定 | ~/.ssh/id_ed25519を指定してreport.txtの転送完了 | |
| -r | フォルダー内のファイルとサブフォルダーまでコピー | 受信側にcssとimagesのフォルダーが元の構造のまま残る、外すと[not a regular file]エラーで転送されない | |
| -p | コピー元の更新時刻とアクセス時刻、権限を保持 | 更新時刻は保持、この記事の受信側では権限600は-O -pで送ったファイルだけ保持 | |
| -C | SSH接続でデータを圧縮 | この記事のサーバー2台の間の19MBのログでは、付けた側が少し遅い | |
| -l | 転送速度の上限をKbit/s単位で指定 | -l 8000で20MBが996.5KB/s、20.82秒 | |
| -v | 接続から転送までの過程をdebug1の行で出力 | [Sending subsystem: sftp]の行でSFTP転送を確認 | |
| -3 | リモートサーバー2台の間のデータをコマンドを実行したサーバー経由で転送(OpenSSH 8.7からの既定の方式) | 同じサーバーの2つのフォルダーをコピー元とコピー先にしてreport.txtの転送完了 | |
| -O | 古いSCPプロトコルで転送 | -vの出力に[Sending command: scp -v -t]が表示される、空白を含むパスはバックスラッシュがさらに必要 | |
| -o | ssh_config形式のオプションをsshに渡す | ConnectTimeout=10で待ち時間を10秒にして[Connection timed out]を確認 |
📎 その他のオプション: 公式マニュアルより
| オプション | 作業 | |
|---|---|---|
| -q | 進捗表示とsshの警告、診断メッセージをオフにする | |
| -J | ジャンプホストに先に接続し、そこから最終的な宛先までTCP転送を設定(ProxyJump設定の省略指定、複数のホップはカンマで区切る) | |
| -F | sshのユーザー別設定ファイルを別のファイルに指定(sshにそのまま渡す) | |
| -4 | IPv4アドレスだけを使うよう強制 | |
| -6 | IPv6アドレスだけを使うよう強制 |
3️⃣ scpでのフォルダーコピーと時刻の保持
フォルダーをオプションなしで指定すると、scpは通常のファイルではないというエラーを出力し、転送を行いません。
scp site-files user@203.0.113.10:~/scp-test/scp: local "site-files" is not a regular file
scp: failed to upload file site-files to ~/scp-test/-rを付けると、フォルダー内のファイルとサブフォルダーまでコピーします。
scp -r site-files user@203.0.113.10:~/scp-test/logo.png 100% 48KB 4.7MB/s 00:00
style.css 100% 15 5.0KB/s 00:00
index.html 100% 15 5.2KB/s 00:00出力にはファイル名だけが表示されます。受信側のfindの出力には、site-filesの下にcssとimagesのフォルダーが元の構造のまま入っていました。
ssh user@203.0.113.10 'cd ~/scp-test && find site-files'site-files
site-files/images
site-files/images/logo.png
site-files/index.html
site-files/css
site-files/css/style.css-rはフォルダー内のシンボリックリンクをたどって元のファイルをコピーするため、リンクをリンクのまま移す必要があるフォルダーにはrsync -aが適しています。
-pはコピー元の更新時刻とアクセス時刻、権限を保持します。元のreport.txtは更新時刻を2026年10月1日 00:00(UTC)、権限を600に合わせてから送りました。受信側サーバーのタイムゾーンがUTCなので、送信側のlsもTZ=UTCで出力しました。
TZ=UTC ls -l report.txt-rw------- 1 root root 14 Oct 1 00:00 report.txtscp -p report.txt user@203.0.113.10:~/scp-test/report-p.txtreport.txt 100% 14 4.7KB/s 00:00scp -O -p report.txt user@203.0.113.10:~/scp-test/report-Op.txtreport.txt 100% 14 4.2KB/s 00:00ssh user@203.0.113.10 'ls -l ~/scp-test/report.txt ~/scp-test/report-p.txt ~/scp-test/report-Op.txt'-rw------- 1 user user 14 Oct 1 00:00 /home/user/scp-test/report-Op.txt
-rw-rw-r-- 1 user user 14 Oct 1 00:00 /home/user/scp-test/report-p.txt
-rw-rw-r-- 1 user user 14 Oct 28 06:17 /home/user/scp-test/report.txt-pで送ったreport-p.txtと-O -pで送ったreport-Op.txtは元の時刻が保持され、オプションなしで送ったreport.txtは送った時刻で保存されました。受信側サーバーでは、SFTPで送ったファイルの権限は-pを付けても664で保存され、古いSCPプロトコル(-O)で送ったファイルだけ600が保持されました。
そのため、権限までコピー元と同じにする必要があるファイルは、送った後に受信側でls -lで権限を確認します。
4️⃣ scpでのポートとキーファイルの指定
既定のポート22と既定のキーで接続できないサーバーは、送る前にポートとキーを直接指定します。-PはSSH接続ポートを、-iは公開鍵認証に使う秘密鍵ファイルを指定します。
以下はポート22とキーファイルを直接指定した例です。ポートを変更したサーバーなら、22の代わりにその番号を書きます。
scp -P 22 -i ~/.ssh/id_ed25519 report.txt user@203.0.113.10:~/scp-test/report.txt 100% 14 5.3KB/s 00:00-iなしで実行すると、sshと同じように~/.sshの下にある既定の名前のキー(id_rsa、id_ecdsa、id_ed25519など)を順に使います。
同じサーバーへよく送るなら、~/.ssh/configに別名を書いておき、scpでは別名だけを入力します。
Host myserver
HostName 203.0.113.10
User user
Port 22
IdentityFile ~/.ssh/id_ed25519Hostの行の名前が別名になり、その下の4行がサーバーのアドレスとアカウント、ポート、キーファイルの代わりになります。別名だけを書いたコマンドも、アドレスとキーをすべて書いたときと同じ1行の結果で終わりました。
scp report.txt myserver:~/scp-test/report.txt 100% 14 4.2KB/s 00:00-Pと-i、別名はいずれもssh接続の設定をそのまま使うため、キーを作成してサーバーに登録する手順も SSHコマンドで接続するときと同じです。
5️⃣ scpでのサーバー間コピー
コピー元とコピー先がどちらもリモートサーバーでも、scp 1行でコピーできます。OpenSSH 8.7からはデータがコマンドを実行したサーバーを経由して転送され、この方式が-3です。公式リリースノートは、コピー元サーバーにコピー先サーバーの認証情報を置かなくて済むことを、既定の方式に変えた理由に挙げています。
以下の実測は、コピー元とコピー先を同じサーバーの2つのフォルダーにして実行しました。コピー先のサーバーが異なる場合は、後ろのアカウントとアドレスだけを変えます。
scp -3 user@203.0.113.10:~/scp-test/report.txt user@203.0.113.10:~/scp-test/copy3/report.txt 100% 14 2.5KB/s 00:00支店2か所の間の書類を本社が受け取って送り直すのと同じです。
コピー元サーバーがコピー先サーバーへ直接送っていた以前の方式は-Rで指定します。この方式では、コピー元サーバーからコピー先サーバーへパスワードなしで接続できる必要があります。OpenSSH 10.6からは-Rを使うと非推奨の警告が表示され、以降のバージョンではこのオプションを無視して-3の方式でコピーする予定です。
6️⃣ scpとrsyncの比較
ファイルを数個1回送るだけならscpで十分で、同じフォルダーを繰り返し同期したり、途切れた転送を再開したりする作業には rsyncコマンドが適しています。scpは実行のたびに指定したファイル全体を送り直し、rsyncはコピー元とコピー先を比較して変更されたファイルだけを転送します。
| 項目 | scp | rsync |
|---|---|---|
| 転送範囲 | 実行のたびに指定したファイル全体 | コピー元と比較して変更されたファイルのみ |
| 途中まで受信したファイルの保持(--partial) | ❌ | ✅ |
| コピー元にないファイルの削除(--delete) | ❌ | ✅ |
| シンボリックリンク | たどって元のファイルをコピー | -aでリンクのまま |
| 受信側に必要なもの | SSH接続とSFTPサーバー | 両側ともrsyncをインストール |
7️⃣ scpコマンドのエラーメッセージと対処
scpが失敗すると、原因は出力の1行目にそのまま表示されます。存在しないファイル、書き込み権限、誤ったポートで意図的にエラーを起こした3つのケースすべてで1行目に原因が表示され、終了コードもすべて0ではありませんでした。
🔲 No such file or directory
リモート側に存在しないファイルを受信しようとすると、パスとともに[No such file or directory]が出力されます。
scp user@203.0.113.10:~/scp-test/nofile.txt ./downloads/scp: ~/scp-test/nofile.txt: No such file or directory送信時にコピー先のフォルダーがなくても同じエラーになります。scpは存在しないフォルダーを作成しないため、sshでmkdir -pを先に実行してフォルダーを作成します。
scp report.txt user@203.0.113.10:~/scp-test/nodir/sub/scp: dest open "scp-test/nodir/sub/": No such file or directory
scp: failed to upload file report.txt to ~/scp-test/nodir/sub/🔲 Permission denied
受信側のフォルダーに書き込み権限がないと、[dest open]の後に[Permission denied]が続きます。以下は権限を555にしたreadonlyフォルダーへ送った結果です。
scp report.txt user@203.0.113.10:~/scp-test/readonly/scp: dest open "scp-test/readonly/report.txt": Permission denied
scp: failed to upload file report.txt to ~/scp-test/readonly/[Permission denied]の前に[アカウント@サーバーアドレス:]が付き、かっこ内にpublickeyのような認証方式が入っている場合は、接続の認証段階で拒否されたケースです。この文言はsshプログラムが認証に失敗したときに出す形式なので、-iで指定したキーファイルとサーバーに登録した公開鍵から確認します。
🔲 Connection timed out
ポート番号が間違っているか、ファイアウォールがそのポートをブロックしていて応答がないと、接続を待った末に[Connection timed out]で終わります。以下は待ち時間を10秒にして、開いていないポート2222へ送った結果です。
scp -P 2222 -o ConnectTimeout=10 report.txt user@203.0.113.10:~/scp-test/ssh: connect to host 203.0.113.10 port 2222: Connection timed out
scp: Connection closedこのエラーが出たら、-Pに書いた番号がサーバーのSSHポートと同じかどうかから確認します。
🔲 パスの空白とチルダ(~)
SFTPで転送する現在のscpは、空白を含むリモートパスをシングルクォートで1回囲むだけで済みます。
scp report.txt 'user@203.0.113.10:~/scp-test/my files/'report.txt 100% 14 4.7KB/s 00:00同じコマンドに-Oを付けて古いSCPプロトコルで送ってみると、[ambiguous target]で失敗しました。古いSCPプロトコルではリモートシェルがパスをもう一度解釈するためです。
scp -O report.txt 'user@203.0.113.10:~/scp-test/my files/'scp: ambiguous targetこの場合は空白の前にバックスラッシュを入れ、リモートシェルでも1つの単語として読まれるようにします。
scp -O report.txt 'user@203.0.113.10:~/scp-test/my\ files/'report.txt 100% 14 4.5KB/s 00:00コロンの後のパスをスラッシュやチルダなしで始めると、リモートアカウントのホームフォルダーを基準に処理されます。
scp report.txt user@203.0.113.10:scp-test/report-rel.txtreport.txt 100% 14 5.6KB/s 00:00公式マニュアルは、古いSFTPサーバーがチルダで始まるパスをホームフォルダーに展開できないときに-Oを使うよう説明しています。この場合は、上のようにチルダなしでホーム基準のパスを書いても同じ場所に保存されます。
🔢 FAQ & おすすめコンテンツ









ℹ️ 提携について
当サイトのコンテンツにはアフィリエイトリンクが含まれています。訪問者がこのリンクを通じて商品やサービスを購入すると、当サイトは販売元から手数料を受け取ります。この過程において、購入者が支払う金額(イベント割引適用で金額が下がります↓)は上昇しません。掲載されている価格・割引・在庫情報は作成時点のものであり、実際とは異なる場合がありますので、ご購入前に販売元にて最終確認をお願いいたします。商品の選定および評価は独自の基準に基づいて行われており、手数料の支払いの有無は紹介順や評価内容に影響を与えません。
