「scpコマンドを使えと言われたけど、書き方がよく分からない」
Linux環境でのファイル転送は、FTPのようにパスワードが平文で流れる方法を使ってしまうと、セキュリティ事故に直結します。現場では、SSH暗号化を利用したscpコマンドが標準的な転送手段です。
この記事では、scpコマンドの基本的な使い方から、公開鍵認証でのパスワード省略、ディレクトリごとの一括転送、ポート番号の変更、そしてトラブル発生時の対処法まで、実務で必要な知識を一通り解説します。
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
scpコマンドとは?SSHベースのファイル転送
scpは「Secure Copy Protocol」の略で、SSHプロトコルを使ってファイルをリモートサーバーとの間で安全に転送するコマンドです。FTPやrcp(Remote Copy)との違いは、通信が暗号化される点にあります。パスワードもファイルの中身も、ネットワーク上では全て暗号化された状態で流れるため、盗聴のリスクがありません。
scpの特徴を整理すると、以下のとおりです。
・SSH暗号化:通信内容が全て暗号化されるため、安全にファイルを転送できる
・追加インストール不要:SSHが使える環境なら、scpもそのまま使える
・操作が簡単:cpコマンドに近い書式で、ローカル・リモート間のコピーができる
・公開鍵認証対応:パスワード入力なしでの自動転送も可能
SSHでログインできるサーバーであれば、特別な設定なしにscpが使えます。「SSHは入れるけどファイル転送はどうすれば?」という場面で、まず使うべきコマンドです。
scpの基本的な使い方
1. ローカルからリモートへファイルを送る
最も基本的な使い方は、手元のファイルをリモートサーバーへコピーするパターンです。# scp local-to-remote $ scp /home/user/backup.tar.gz admin@192.168.1.10:/tmp/ admin@192.168.1.10's password: backup.tar.gz 100% 256KB 12.8MB/s 00:00
scp 送信元ファイル ユーザー名@ホスト名:転送先パスコロン(:)の後に転送先のディレクトリを指定します。コロンの後を省略すると、リモート側のホームディレクトリに転送されます。
# ホームディレクトリに転送される $ scp /home/user/backup.tar.gz admin@192.168.1.10:
2. リモートからローカルへファイルを取得する
送信元と転送先を逆にすれば、リモートのファイルをローカルに取得できます。# リモートの/var/log/messages をローカルのカレントディレクトリに取得する $ scp admin@192.168.1.10:/var/log/messages ./ messages 100% 128KB 10.2MB/s 00:00
3. ディレクトリごと転送する(-rオプション)
ディレクトリを丸ごとコピーしたい場合は、-r(recursive)オプションを付けます。# ローカルの/home/user/project/ をリモートの/opt/に丸ごと転送する $ scp -r /home/user/project/ admin@192.168.1.10:/opt/
-rを付け忘れると「not a regular file」というエラーが出ます。ディレクトリ転送で失敗する場合は、まず-rの付け忘れを疑ってください。4. ポート番号を変更して転送する(-Pオプション)
SSHのポート番号がデフォルトの22番から変更されている場合は、-Pオプションで指定します。# SSHポートが10022番の場合 $ scp -P 10022 /home/user/data.csv admin@192.168.1.10:/tmp/
-Pです。sshコマンドでは小文字の-pでポートを指定しますが、scpでは-pはタイムスタンプ保持のオプションになっているため、間違えやすいポイントです。実務で使うscpのオプションと応用
1. タイムスタンプとパーミッションを保持する(-pオプション)
ファイルの更新日時やパーミッションをそのまま維持して転送したい場合は、小文字の-pを付けます。# タイムスタンプとパーミッションを保持して転送する $ scp -p /home/user/config.conf admin@192.168.1.10:/etc/myapp/
-pを付けておくと、転送後のファイルがいつ作成されたものか分からなくなる事態を防げます。2. 転送速度を制限する(-lオプション)
大きなファイルを転送するとネットワーク帯域を圧迫してしまうことがあります。業務時間中に転送する場合は、-lで帯域制限をかけましょう。# 帯域を1000Kbit/sに制限して転送する $ scp -l 1000 /home/user/large_dump.sql admin@192.168.1.10:/tmp/
-lの単位はKbit/秒(キロビット毎秒)です。1000Kbit/sは約125KB/sに相当します。3. 公開鍵認証でパスワードなし転送(-iオプション)
cronで定期的にファイルを自動転送したい場合、毎回パスワードを入力するわけにはいきません。公開鍵認証を使えば、パスワードなしで安全に転送できます。# 秘密鍵を指定して転送する $ scp -i ~/.ssh/id_rsa_backup /home/user/backup.tar.gz admin@192.168.1.10:/backup/
(1)鍵ペアを生成する
# ED25519方式で鍵ペアを生成する $ ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_backup -N ""
# 公開鍵をリモートに転送して登録する $ ssh-copy-id -i ~/.ssh/id_ed25519_backup.pub admin@192.168.1.10
# パスワード入力なしで転送できれば成功 $ scp -i ~/.ssh/id_ed25519_backup /home/user/test.txt admin@192.168.1.10:/tmp/ test.txt 100% 24 1.2KB/s 00:00
4. 圧縮して転送する(-Cオプション)
回線が遅い環境では、-Cオプションで転送データを圧縮できます。# データを圧縮して転送する $ scp -C /home/user/access.log admin@192.168.1.10:/var/log/backup/
5. リモートサーバー間でファイルを転送する
2台のリモートサーバー間でファイルを直接転送することもできます。# サーバーAのファイルをサーバーBに転送する $ scp admin@server-a:/var/log/app.log admin@server-b:/tmp/
scpとrsync・sftpの使い分け
ファイル転送にはscp以外にもrsyncやsftpという選択肢があります。場面に応じた使い分けを知っておきましょう。| 比較項目 | scp | rsync | sftp |
|---|---|---|---|
| 差分転送 | できない(毎回全量転送) | できる(変更分のみ) | できない |
| 転送の中断・再開 | できない | できる(--partialオプション) | 一部対応 |
| 対話操作 | できない | できない | できる(cd, ls, get, put等) |
| 用途 | 単発ファイルの転送 | 定期バックアップ・同期 | ファイルの確認と転送 |
まとめると、以下のように使い分けるのが現場のセオリーです。
・ファイル1~数個を転送したい:scpが最もシンプルで速い
・定期的にバックアップしたい:rsyncの差分転送が効率的
・リモートのファイルを確認しながら転送したい:sftpの対話モードが便利
「Permission denied」が出た時の対処法
scpで最も多いエラーが「Permission denied」です。原因は大きく3つあります。1. パスワードまたは鍵の認証エラー
# エラー例 admin@192.168.1.10: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
・リモートの
~/.ssh/authorized_keysに公開鍵が正しく追記されているか・
~/.ssh/ディレクトリのパーミッションが700か・
~/.ssh/authorized_keysのパーミッションが600か# リモート側でパーミッションを修正する $ chmod 700 ~/.ssh $ chmod 600 ~/.ssh/authorized_keys
2. 転送先ディレクトリの書き込み権限がない
# エラー例 scp: /opt/data/file.txt: Permission denied
# リモート側でディレクトリの権限を確認する $ ls -ld /opt/data/ drwxr-xr-x. 2 root root 4096 Apr 1 10:00 /opt/data/
3. SELinuxによるブロック
パーミッションは正しいのにPermission deniedが出る場合は、SELinuxが原因の可能性があります。# SELinuxの状態を確認する $ getenforce Enforcing # 一時的にSELinuxを無効にして転送を試す(検証目的のみ) $ sudo setenforce 0
「Connection refused」が出た時の対処法
# エラー例 ssh: connect to host 192.168.1.10 port 22: Connection refused
・SSHサービスが起動していない:リモート側で
systemctl status sshdを確認する・ファイアウォールでブロックされている:SSHのポート(デフォルト22番)が開放されているか確認する
・ポート番号が違う:
-Pオプションで正しいポートを指定するまずはsshコマンドで直接ログインできるか試してください。sshでログインできない環境では、scpも使えません。
# SSHでログインできるか確認する $ ssh admin@192.168.1.10
scpコマンド実行時のデバッグ方法
原因が特定できない場合は、-vオプションで詳細ログを出力させると手がかりが得られます。# 詳細ログを表示して転送する $ scp -v /home/user/test.txt admin@192.168.1.10:/tmp/
-vを付けると、SSH接続の各段階(DNS解決、TCP接続、認証方式の選択、鍵の照合など)が順番に表示されます。どの段階で失敗しているかが一目で分かるので、トラブル時にはまず-vを付けて再実行してください。さらに詳細なログが必要な場合は、
-vvvのようにvを重ねることで出力量を増やせます。本記事のまとめ
| やりたいこと | コマンド |
|---|---|
| ローカルからリモートへ転送 | scp ファイル ユーザー@ホスト:パス |
| リモートからローカルへ取得 | scp ユーザー@ホスト:パス ローカルパス |
| ディレクトリごと転送 | scp -r ディレクトリ ユーザー@ホスト:パス |
| ポート番号を指定して転送 | scp -P ポート番号 ファイル ユーザー@ホスト:パス |
| タイムスタンプを保持して転送 | scp -p ファイル ユーザー@ホスト:パス |
| 帯域制限をかけて転送 | scp -l 1000 ファイル ユーザー@ホスト:パス |
| 公開鍵を指定して転送 | scp -i 秘密鍵パス ファイル ユーザー@ホスト:パス |
| 圧縮して転送 | scp -C ファイル ユーザー@ホスト:パス |
| デバッグログを出力 | scp -v ファイル ユーザー@ホスト:パス |
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
※登録30秒/合わなければ解除3秒
