scpとsftpとは、SSHの暗号化された通信を使って、手元のPCとサーバーの間でファイルを送受信するコマンドです。scpは cp のように1行で転送でき、sftpは対話形式(またはバッチファイル)で、一覧表示・移動・削除・名前変更などをしながら転送できます。どちらもOpenSSHに含まれているので、SSHでログインできるサーバーなら追加のインストールなしで使えます。

この記事では、scpのオプション一覧とsftpのコマンド一覧を、すべて実行ログつきで紹介します。検証はUbuntu 24.04(OpenSSH 9.6p1)で、ローカルに2台分のsshd(接続先と踏み台)を起動して行いました。上位記事にはあまりない、OpenSSH 9.0以降でscpがSFTPを使うようになったことによる「空白・特殊文字・ワイルドカード」の違いの実測、踏み台経由(-J)とサーバー間転送(-3)、Host key verification failed と Permission denied (publickey) の再現と直し方、scp・sftp・rsyncの使い分け表までまとめています。

scp・sftpの早見表

scp:よく使う書き方

やりたいこと コマンド
ファイルを送る(アップロード) scp report.txt user@host:/path/to/dir/
ファイルを受け取る(ダウンロード) scp user@host:/path/report.txt ./
フォルダごと送る scp -r docs user@host:/path/to/dir/
ポートを指定 scp -P 2222 report.txt user@host:dir/(大文字のP)
鍵を指定 scp -i ~/.ssh/id_ed25519 report.txt user@host:dir/
更新日時と権限を保つ scp -p report.txt user@host:dir/
速度を制限 scp -l 8192 big.log user@host:dir/(単位はKbit/s。8192で約1MB/s)
踏み台経由 scp -J bastion report.txt target:dir/
サーバーAからサーバーBへ scp -3 hostA:file hostB:dir/
~/.ssh/config のHost名を使う scp report.txt demo:dir/

scpのオプション一覧

オプション 意味 補足
-P ポート 接続先のポート sshは小文字 -p、scpは大文字 -P
-i 鍵ファイル 秘密鍵を指定 複数の鍵がある場合は -o IdentitiesOnly=yes と一緒に
-r フォルダを再帰的にコピー 付けないとフォルダは not a regular file エラー
-p 更新日時・アクセス日時・権限を保つ 小文字。バックアップの日時を残したいとき
-C 通信を圧縮 遅い回線でテキストを送るときに有効。速い回線ではCPU負荷の分だけ遅くなることも
-l 帯域 速度の上限(Kbit/s) 業務時間中に回線を占有しないために
-3 リモート間のコピーを手元経由で行う 2台のサーバーが直接つながらないときに
-O 旧来のSCPプロトコルで転送 OpenSSH 9.0以降の既定はSFTP。SFTP非対応のサーバーで失敗するときに
-J 踏み台 ProxyJump(踏み台経由) -J user@bastion:22 のように書ける。カンマ区切りで多段も可
-o 設定 ssh_configの設定を1回だけ指定 -o ConnectTimeout=5、-o StrictHostKeyChecking=accept-new など
-F ファイル 使う設定ファイルを指定 既定は ~/.ssh/config
-q 進捗表示や警告を出さない スクリプト向け
-v 詳細ログ 接続できないときの調査に
-B バッチモード(パスワード入力を求めない) cronなどで止まらないように

sftp:コマンド一覧

コマンド 意味 例
put アップロード put report.txt、put -r docs
get ダウンロード get renamed.txt、get -r docs
reput / reget 途中から再開 reput big.bin
ls / lls リモート/ローカルの一覧 ls -l、ls *.txt
cd / lcd リモート/ローカルの移動 lcd ~/Downloads
pwd / lpwd リモート/ローカルの現在地
mkdir / rmdir フォルダ作成/削除(空のみ) mkdir sftp_test
rm ファイル削除 rm renamed.txt
rename 名前変更・移動 rename report.txt renamed.txt
chmod 権限変更 chmod 600 renamed.txt
df -h リモートの空き容量
!コマンド ローカルでコマンドを実行 !ls -la
exit / bye 終了
sftpの起動オプション 意味
-P ポート ポート(scpと同じ大文字)
-i 鍵 / -J 踏み台 / -o 設定 scpと同じ
-b ファイル バッチファイルのコマンドを順に実行(-b - で標準入力から)
-r put / get を常に再帰にする

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「scp・sftpコマンドの使い方|オプション一覧と転送パターン集」

検証環境と前提

実行ログは次の環境で取りました。接続先は demo(ポート7091)、踏み台は bastion(ポート7090)というHost名で ~/.ssh/config 相当の設定ファイルに登録し、どちらも同じ検証用ユーザー t109u でログインしています。

OS       : Ubuntu 24.04.4 LTS
OpenSSH  : OpenSSH_9.6p1 Ubuntu-3ubuntu13.19, OpenSSL 3.0.13
sshd     : 127.0.0.1:7091(demo)、127.0.0.1:7090(bastion)、公開鍵認証のみ
# 検証に使った ~/.ssh/config 相当の内容
Host demo
    HostName 127.0.0.1
    Port 7091
    User t109u
    IdentityFile ~/.ssh/id_test

Host bastion
    HostName 127.0.0.1
    Port 7090
    User t109u
    IdentityFile ~/.ssh/id_test

~/.ssh/config にHost名を登録しておくと、scp report.txt demo:up/ のように短く書けます。ポート・ユーザー・鍵を毎回書く必要がなくなり、打ち間違いも減ります。configの書き方の詳細は、既存の「ssh configの書き方」記事にまとめています。

なお、ログ中の転送は端末(TTY)のない状態で実行したため、進捗バー(report.txt 100% 6 ...)は表示されていません。また、読みやすさのため、検証用の設定ファイル指定(-F)や known_hosts の指定(-o UserKnownHostsFile=...)はコマンド表示から省き、長い作業フォルダのパスは /home/user/... に置き換えています。

scpの基本:送る・受け取る・フォルダごと

書式は scp [オプション] コピー元 コピー先 で、リモート側は ユーザー@ホスト:パス と書きます。パスが / で始まらなければ、ログインユーザーのホームからの相対パスです。

$ scp report.txt demo:up/
scp: dest open "up/": Failure
scp: failed to upload file report.txt to up/

$ ssh demo 'mkdir -p up dl'

$ scp report.txt demo:up/

$ scp demo:up/report.txt ./dl_report.txt

$ scp docs demo:up/
scp: local "docs" is not a regular file
scp: failed to upload file docs to up/

$ scp -r docs demo:up/

$ ssh demo 'find up | sort'
up
up/docs
up/docs/a.md
up/docs/b.md
up/docs/img
up/docs/img/logo.png
up/report.txt

送り先のフォルダが無いと dest open "up/": Failure になります。scpはフォルダを途中まで作ってくれないので、ssh host 'mkdir -p ...' で先に作ります。フォルダは -r を付けないと not a regular file になります。

送り先のフォルダが「ある」か「ない」かで結果が変わる

scp -r docs demo:up/newdir を2回続けて実行した結果です。

$ scp -r docs demo:up/newdir && ssh demo 'find up/newdir | sort'
up/newdir
up/newdir/a.md
up/newdir/b.md
up/newdir/img
up/newdir/img/logo.png

$ scp -r docs demo:up/newdir && ssh demo 'find up/newdir | sort'
up/newdir
up/newdir/a.md
up/newdir/b.md
up/newdir/docs
up/newdir/docs/a.md
up/newdir/docs/b.md
up/newdir/docs/img
up/newdir/docs/img/logo.png
up/newdir/img
up/newdir/img/logo.png

1回目は newdir が無いので「docs の中身が newdir という名前で」作られ、2回目は newdir があるので「newdir の中に docs が」作られました。同じコマンドでも結果が変わるので、スクリプトでは送り先を up/ のように「必ず存在する親フォルダ」にしておくと結果が安定します。

scpのオプションを1つずつ実行して確かめる

-P と -i:ポートと鍵を指定する

$ scp -i ~/.ssh/id_test -P 7091 report.txt t109u@127.0.0.1:up/by_ip.txt && echo OK
OK

-P は大文字です。小文字の -p は「日時と権限を保つ」という別の意味になります。

-p:更新日時を保つ

ローカルの report.txt の更新日時は 2026-01-15 10:00 にしてあります。

$ scp report.txt demo:up/
$ scp -p report.txt demo:up/report_p.txt
$ ssh demo 'ls -l --time-style=long-iso up/report.txt up/report_p.txt'
-rw-r--r-- 1 t109u t109u 6 2026-10-02 00:25 up/report.txt
-rw-r--r-- 1 t109u t109u 6 2026-01-15 10:00 up/report_p.txt

-p なしは転送した時刻、-p ありは元の日時(2026-01-15 10:00)になりました。

-C と -l:圧縮と速度制限

20MBのテキスト(big.log)とランダムなバイナリ(big.bin)を、同じマシン内のsshdに送った時間です。

$ time scp big.log demo:up/          → real 0m0.498s
$ time scp -C big.log demo:up/       → real 0m0.548s
$ time scp big.bin demo:up/          → real 0m0.495s
$ time scp -C big.bin demo:up/       → real 0m0.918s
$ time scp -l 8192 mid.log demo:up/  → real 0m4.265s   (mid.log は4MB)

回線が速い(今回は同じマシン内)と、-C は圧縮のCPU時間の分だけ遅くなりました。特に圧縮が効かないバイナリでは約1.9倍の時間です。-C は回線が遅く、テキストのように圧縮が効くファイルで選びます。-l 8192(約1MB/s)では4MBが約4.3秒で、指定どおりに速度が抑えられています。

-3:サーバーAからサーバーBへ手元経由でコピー

$ time scp -3 demo:up/report.txt bastion:report_from_demo.txt
real    0m0.503s

$ ssh bastion 'ls -l report_from_demo.txt'
-rw-r--r-- 1 t109u t109u 6 Oct  2 00:26 report_from_demo.txt

-3 を付けると、データは「demo → 手元 → bastion」と流れます。2台のサーバー同士が直接通信できない場合や、片方のサーバーにもう片方の鍵を置きたくない場合に便利です。手元の回線を通るので、大きなファイルでは時間がかかります。

-J:踏み台サーバー経由

$ scp -J bastion report.txt demo:up/via_jump.txt && ssh demo 'ls up/via_jump.txt'
up/via_jump.txt

$ scp -v -J bastion report.txt demo:up/via_jump.txt 2>&1 | grep -E 'Executing|ProxyJump|Authenticated to'
Executing: program /usr/bin/ssh host demo, user (unspecified), command sftp
debug1: Setting implicit ProxyCommand from ProxyJump: /usr/bin/ssh -v -W '[%h]:%p' bastion
Authenticated to 127.0.0.1 ([127.0.0.1]:7090) using "publickey".
Authenticated to 127.0.0.1 (via proxy) using "publickey".

まず踏み台(7090)に認証し、そこから -W で接続先(7091)へトンネルを張って認証しています。秘密鍵は手元にだけ置けばよく、踏み台に鍵を置く必要はありません。毎回使うなら ~/.ssh/config の接続先に ProxyJump bastion と書けば、-J は不要になります(ログ中の -F 設定ファイル の表示は省略しています)。

-o:ssh_configの設定を一時的に指定

$ scp -o ConnectTimeout=3 -P 7099 report.txt t109u@127.0.0.1:up/
ssh: connect to host 127.0.0.1 port 7099: Connection refused
scp: Connection closed

$ scp -o Compression=yes -o Port=7091 -i ~/.ssh/id_test report.txt t109u@127.0.0.1:up/opt.txt && echo OK
OK

-o には ~/.ssh/config に書ける設定をそのまま渡せます。よく使うのは ConnectTimeout=5(つながらないときに早く諦める)、StrictHostKeyChecking=accept-new(初回のホスト鍵を自動登録)、IdentitiesOnly=yes(指定した鍵だけを使う)です。

OpenSSH 9.0以降のscpはSFTPで動く(-O で旧方式)

OpenSSH 9.0(2022年4月)から、scpは内部で旧来のSCP/RCPプロトコルではなくSFTPプロトコルを使うようになりました。公式リリースノートには、旧方式ではリモートのシェルがファイル名を解釈するため、特殊文字を二重にクォートする必要があったこと、SFTPではそれが不要になったこと、問題があれば -O で旧方式に戻せることが書かれています。-v で確かめると、違いがはっきりわかります。

$ scp -v report.txt demo:up/v.txt 2>&1 | grep -iE 'sftp|Sending command|subsystem'
Executing: program /usr/bin/ssh host demo, user (unspecified), command sftp
debug1: Sending subsystem: sftp

$ scp -O -v report.txt demo:up/v.txt 2>&1 | grep -iE 'sftp|Sending command|subsystem'
debug1: Sending command: scp -v -t up/v.txt

既定(SFTP)は subsystem: sftp、-O はリモートで scp -t コマンドを実行しています。

空白・特殊文字・ワイルドカードの違いを実測

リモートに my file.txt(空白入り)と a;b.txt(セミコロン入り)を作って、両方の方式で受け取りました。

$ scp 'demo:up/my file.txt' ./got1.txt && cat got1.txt
space

$ scp -O 'demo:up/my file.txt' ./got2.txt
scp: up/my: No such file or directory
scp: file.txt: No such file or directory

$ scp -O 'demo:up/my\ file.txt' ./got2.txt && cat got2.txt
space

$ scp 'demo:up/a;b.txt' ./got3.txt && cat got3.txt
semi

$ scp -O 'demo:up/a;b.txt' ./got4.txt
scp: up/a: No such file or directory
bash: line 1: b.txt: command not found

$ scp 'demo:up/docs/*.md' g1/ && ls g1
a.md
b.md

$ scp -O 'demo:up/docs/*.md' g2/ && ls g2
a.md
b.md

$ scp 'demo:~/up/report.txt' ./tilde.txt && cat tilde.txt
hello
書き方 既定(SFTP方式) -O(旧SCP方式)
空白入り 'host:my file.txt' そのまま取れる 2つのファイル名に分かれる。'host:my\ file.txt' と二重に書けば取れる
; などシェル記号入り そのまま取れる リモートのシェルが ; をコマンドの区切りと解釈する
ワイルドカード 'host:docs/*.md' 取れる(sftp側で展開) 取れる(リモートのシェルで展開)
~ で始まるパス 取れる(サーバーがOpenSSH 8.7以降の場合) 取れる
SFTPに対応していない・無効にしたサーバー 失敗することがある こちらで転送できる

ワイルドカードは手元のシェルに展開されないよう '...' で囲むのが両方式共通のコツです。特殊文字を含むファイル名は既定のSFTP方式のまま、SFTP非対応のサーバーでうまくいかないときだけ -O と覚えておくと迷いません。

sftpの使い方:対話・ワンライナー・バッチ

バッチファイルでまとめて実行する(-b)

-b にコマンドを書いたファイルを渡すと、上から順に実行して終了します。対話で打つ内容と同じです。下のバッチで主なコマンドを一通り実行しました。

pwd
lpwd
mkdir sftp_test
cd sftp_test
put report.txt
put -r docs
ls -l
rename report.txt renamed.txt
ls
chmod 600 renamed.txt
ls -l renamed.txt
lcd dl_sftp
get renamed.txt
get -r docs
lls
rm renamed.txt
-rm not_exist.txt
ls
$ sftp -b batch.txt demo
sftp> pwd
Remote working directory: /home/t109u
sftp> lpwd
Local working directory: /home/user/work
sftp> mkdir sftp_test
sftp> cd sftp_test
sftp> put report.txt
sftp> put -r docs
Entering docs/
Entering docs/img
sftp> ls -l
drwxr-xr-x    ? t109u    t109u        4096 Oct  2 00:26 docs
-rw-r--r--    ? t109u    t109u           6 Oct  2 00:26 report.txt
sftp> rename report.txt renamed.txt
sftp> ls
docs         renamed.txt  
sftp> chmod 600 renamed.txt
sftp> ls -l renamed.txt
-rw-------    ? t109u    t109u           6 Oct  2 00:26 renamed.txt
sftp> lcd dl_sftp
sftp> get renamed.txt
sftp> get -r docs
Retrieving /home/t109u/sftp_test/docs
Retrieving /home/t109u/sftp_test/docs/img
sftp> lls
docs
renamed.txt
sftp> rm renamed.txt
sftp> -rm not_exist.txt
remote delete /home/t109u/sftp_test/not_exist.txt: No such file or directory
sftp> ls
docs  
$ echo $?
0

(lpwd の出力は、実際の作業フォルダのパスを /home/user/work に置き換えています。)

コマンドの先頭に - を付けると、失敗しても次へ進みます。付けない場合は、失敗した時点で止まり、終了コードが1になります。

$ printf 'cd sftp_test\nrm not_exist.txt\nls\n' > batch2.txt
$ sftp -b batch2.txt demo
sftp> cd sftp_test
sftp> rm not_exist.txt
remote delete /home/t109u/sftp_test/not_exist.txt: No such file or directory
$ echo $?
1

後ろの ls は実行されていません。cronやCIでは、この終了コードで成否を判定できます。-b を使うとパスワード入力を求めないバッチモードになるので、公開鍵認証が前提です。

ワンライナーとヒアドキュメント

$ sftp demo:up/report.txt ./one.txt
Connected to demo.
Fetching /home/t109u/up/report.txt to ./one.txt

$ sftp demo:up <<< 'ls -1 *.txt'
Connected to demo.
Changing to: /home/t109u/up
sftp> ls -1 *.txt
a;b.txt
by_ip.txt
my file.txt
...

sftp ホスト:ファイル ローカル で1ファイルだけ取得でき、sftp ホスト:フォルダ で最初からそのフォルダに入った状態で始められます。

途中で切れた転送を再開する(reput / reget)

20MBのうち3MBだけ送った状態から、reput で続きを送りました。

$ sftp demo <<< $'cd up\nreput big.bin big_resume.bin'
Connected to demo.
sftp> cd up
sftp> reput big.bin big_resume.bin
Resuming upload of big.bin to /home/t109u/up/big_resume.bin

$ ssh demo 'ls -l up/big_resume.bin'
-rw-r--r-- 1 t109u t109u 20971520 Oct  2 00:27 up/big_resume.bin

$ cmp big.bin <(ssh demo 'cat up/big_resume.bin') && echo SAME
SAME

再開後のファイルは元と完全に一致しました。scpには再開の機能がないので、大きなファイルで回線が不安定なときは sftp の reput / reget、または rsync の --partial を使います。

scp・sftp・rsyncの使い分け

観点 scp sftp rsync
書き方 1行で cp と同じ感覚 対話またはバッチ 1行。オプションが豊富
2回目以降 毎回すべて送る 毎回すべて送る 差分だけ送る
途中からの再開 なし reput / reget --partial / -P
一覧・削除・名前変更 できない(sshで別途) できる --delete で同期のみ
サーバー側の準備 SSHだけ SSHだけ(SFTPサブシステム) 両側にrsyncが必要
SFTP専用アカウント(シェルなし) 使える(9.0以降の既定) 使える 使えない
向いている用途 数ファイルをさっと送る ファイルを見ながら操作、取引先との受け渡し フォルダの同期、定期バックアップ、大量ファイル

迷ったら「1〜数ファイルならscp、サーバー上で確認しながらならsftp、フォルダを繰り返しそろえるならrsync」です。rsyncのオプションと実行例は、既存の「rsyncの使い方」記事にまとめています。

よくあるエラーの再現と直し方

Host key verification failed.

初めて接続するサーバーで、ホスト鍵を確認できないときに出ます。対話できる端末なら「yes/no」と聞かれますが、cronやバッチモードでは聞けないためエラーになります。

$ scp -o BatchMode=yes -P 7091 report.txt t109u@127.0.0.1:up/   # known_hostsが空の状態
Host key verification failed.
scp: Connection closed

直し方は、指紋を確かめてから known_hosts に登録することです。サーバー管理者から聞いた指紋と、ssh-keyscan で取得した指紋を比べます。

$ ssh-keyscan -p 7091 -t ed25519 127.0.0.1 2>/dev/null | ssh-keygen -lf -
256 SHA256:qMdvXkcbGIn+N1LKBUen6ndxZGL+1Xe3EqWMvqnDqDY [127.0.0.1]:7091 (ED25519)

# サーバー側で確認した指紋(一致することを確認)
$ ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
256 SHA256:qMdvXkcbGIn+N1LKBUen6ndxZGL+1Xe3EqWMvqnDqDY root@vm (ED25519)

一致を確かめたら、ssh-keyscan ... >> ~/.ssh/known_hosts で追加するか、1回だけ -o StrictHostKeyChecking=accept-new(未登録なら登録、変わっていたら拒否)で接続します。

WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!

known_hosts に登録済みの鍵と、サーバーが提示した鍵が違うときに出ます。サーバーの再構築やOS入れ替えで鍵が変わった場合に起きます。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
...
The fingerprint for the ED25519 key sent by the remote host is
SHA256:qMdvXkcbGIn+N1LKBUen6ndxZGL+1Xe3EqWMvqnDqDY.
...
Offending ED25519 key in /home/user/.ssh/known_hosts:1
  remove with:
  ssh-keygen -f '/home/user/.ssh/known_hosts' -R '[127.0.0.1]:7091'
Host key for [127.0.0.1]:7091 has changed and you have requested strict checking.
Host key verification failed.

サーバー管理者に「鍵を変えたか」を確認し、新しい指紋が正しいとわかってから、メッセージにあるとおり登録済みの行を消します。

$ ssh-keygen -R '[127.0.0.1]:7091'
# Host [127.0.0.1]:7091 found: line 1
/home/user/.ssh/known_hosts updated.
Original contents retained as /home/user/.ssh/known_hosts.old

ポートが22以外のときは [ホスト]:ポート の形で指定します。

Permission denied (publickey).

公開鍵認証に失敗したときのエラーです。クライアント側の原因とサーバー側の原因があり、エラー文だけでは区別できません。3パターンを再現しました。

# ① 登録していない鍵を使った
$ scp -i ~/.ssh/id_wrong -o IdentitiesOnly=yes -P 7091 report.txt t109u@127.0.0.1:up/
t109u@127.0.0.1: Permission denied (publickey).
scp: Connection closed

# ② 手元の秘密鍵の権限が 644
$ scp -i ~/.ssh/id_loose -o IdentitiesOnly=yes -P 7091 report.txt t109u@127.0.0.1:up/
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/home/user/.ssh/id_loose' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "/home/user/.ssh/id_loose": bad permissions
t109u@127.0.0.1: Permission denied (publickey).

# ③ サーバーの authorized_keys が 666、または ~/.ssh が 777
$ scp -i ~/.ssh/id_test -o IdentitiesOnly=yes -P 7091 report.txt t109u@127.0.0.1:up/
t109u@127.0.0.1: Permission denied (publickey).
scp: Connection closed

③のとき、クライアントには同じエラーしか出ませんが、サーバーのログ(sshdのログ、journalctl -u ssh など)には理由が出ます。

Authentication refused: bad ownership or modes for file /home/t109u/.ssh/authorized_keys
Authentication refused: bad ownership or modes for directory /home/t109u/.ssh
確認する場所 正しい状態 直すコマンド
手元の秘密鍵 600(本人だけ読める) chmod 600 ~/.ssh/id_ed25519
使っている鍵 登録した鍵と同じ -i で指定し -o IdentitiesOnly=yes。-v で Offering public key を確認
サーバーの ~/.ssh 700 chmod 700 ~/.ssh
サーバーの authorized_keys 600(または644) chmod 600 ~/.ssh/authorized_keys
サーバーのホームフォルダ 他人が書き込めない chmod go-w ~
ユーザー名 接続先のユーザー user@host の user、configの User

今回の検証では、authorized_keys が 664(グループ書き込み可)では受け付けられ、666(全員書き込み可)で拒否されました。鍵の作り方とGitHubでの同じエラーの対処は、既存の「SSH鍵の作成」記事にまとめています。

そのほかのエラー

エラー 原因 直し方
dest open "up/": Failure 送り先のフォルダがない ssh host 'mkdir -p up' で作る
local "docs" is not a regular file フォルダに -r を付けていない scp -r
Connection refused ポートが違う、sshdが動いていない -P の値、サーバーの ss -ltn を確認
Connection timed out ファイアウォール、経路 -o ConnectTimeout=5 で早めに切り、踏み台経由を検討
subsystem request failed サーバーでSFTPが無効 scpは -O、sftpはサーバー側の Subsystem sftp 設定を確認

よくある質問

Q. scpは使わない方がよいと聞きましたが、本当ですか? A. OpenSSH 9.0以降のscpは内部でSFTPを使うため、以前指摘されていた「リモートのシェルがファイル名を解釈する」問題はなくなっています。数ファイルを送る用途では引き続き便利です。同期や再開が必要ならrsyncやsftpを選ぶ、という使い分けで十分です。

Q. パスワードを聞かれずにcronで転送したいです。 A. パスフレーズなしの専用鍵を作り、サーバーの authorized_keys に登録して、scp -B や sftp -b で実行します。初回のホスト鍵は事前に known_hosts へ登録しておきます。専用鍵は authorized_keys の先頭に restrict などを付けて、できることを絞ると安心です。

Q. Windowsでも使えますか? A. Windows 10/11 には OpenSSH クライアントが標準で入っており、PowerShell やコマンドプロンプトで scp と sftp がそのまま使えます。パスは C:\Users\me\report.txt のように書けます(今回の実行結果はLinuxでのものです)。

Q. 転送したファイルが壊れていないか確認するには? A. 両側でハッシュを比べます。sha256sum report.txt と ssh host 'sha256sum up/report.txt' の値が同じなら一致しています。

まとめ

  • scpは scp コピー元 コピー先、リモートは user@host:パス。フォルダは -r、ポートは大文字の -P
  • 送り先フォルダの有無で scp -r の結果が変わる。送り先は必ず存在する親フォルダにすると安定する
  • -p で日時を保持、-l で速度制限、-3 でサーバー間、-J で踏み台経由。速い回線では -C が逆に遅くなることもある
  • OpenSSH 9.0以降のscpはSFTPで動き、空白や ; を含む名前もそのまま扱える。SFTP非対応のサーバーでは -O
  • sftpは -b でバッチ実行、- を付けたコマンドは失敗しても続行、終了コードで成否を判定できる
  • 再開は sftp の reput / reget、同期は rsync と使い分ける
  • Permission denied (publickey) は秘密鍵600・~/.ssh 700・authorized_keys 600を確認し、理由はサーバーのログで見る

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「scp・sftpコマンドの使い方|オプション一覧と転送パターン集」

株式会社RJCでは、サーバー間のファイル転送のような基本操作を、動かして確かめながら仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?