- ネットワーク
scp・sftpコマンドの使い方|オプション一覧と転送パターン集
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期連続の黒字決算。