scp传包失败主因是目标路径权限不足或用户身份不匹配,应先检查目录权限、优先传至家目录再操作,配合-p、-c、-o等参数适配ssh配置,并考虑rsync替代实现增量同步。

scp 命令传包失败时,先确认目标路径权限和用户身份
直接用 scp 传代码包(比如 app-v1.2.tar.gz)失败,八成不是加密问题,而是目标机器上用户没写权限。常见现象是报错 scp: /path/to/: Permission denied 或静默中断。注意:scp 默认以当前登录用户身份操作,如果目标路径属 root 或其他用户,又没配 sudo 权限,就必然失败。
实操建议:
- 先用
ssh user@host 'ls -ld /target/dir'看目标目录归属和权限 - 优先把包传到该用户的家目录(如
/home/deploy/),再 ssh 进去解压或移动 - 避免在命令里硬写
sudo scp——scp本身不支持远程提权,sudo只作用于本地端 - 若必须写系统目录,改用
rsync -e "ssh -p 2222" app.tar.gz user@host:/tmp/ && ssh user@host "sudo tar -xf /tmp/app.tar.gz -C /opt/app/"
指定端口、跳过校验、压缩传输的常用参数组合
生产环境服务器往往不开 22 端口,或禁用了 known_hosts 校验,这时候裸写 scp file user@host: 会卡住甚至报错。关键不是“能不能传”,而是参数是否匹配实际 SSH 配置。
实操建议:
- 非标端口:用
-P 2222(大写 P),不是小写 p(那是进度条开关) - 跳过 host key 检查(仅测试环境):加
-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null - 启用压缩(对文本类代码包有效):加
-C,能明显提速,但对已压缩的.tar.gz文件几乎无效 - 完整示例:
scp -P 2222 -C -o StrictHostKeyChecking=no app.tar.gz deploy@192.168.1.100:/home/deploy/
传输大包时被断开?调整 SSH 超时与缓冲区
传几百 MB 的构建产物时,scp 经常在 95% 左右卡死或报 Connection reset by peer,这不是网络丢包,而是 SSH 层主动断连。根本原因是服务端或客户端设置了空闲超时(ClientAliveInterval / ServerAliveInterval),而 scp 在传输中不发心跳。
实操建议:
- 临时生效:在
scp命令中嵌套 SSH 配置,如scp -o ServerAliveInterval=30 -o ServerAliveCountMax=3 ... - 长期解决:在
~/.ssh/config中为对应主机配置:Host myserver<br> HostName 192.168.1.100<br> User deploy<br> Port 2222<br> ServerAliveInterval 30<br> ServerAliveCountMax 3
- 别碰
TcpKeepAlive—— 它只管 TCP 层,对 SSH 加密隧道内的应用层断连基本无效
替代方案:rsync over ssh 更适合增量同步代码包
如果你频繁传同一项目的不同版本(比如每次 CI 构建后推新包),scp 每次都全量覆盖,既慢又浪费带宽。rsync 天然支持差异传输,且底层仍走 SSH 加密,安全性不打折。
实操建议:
- 基础同步:
rsync -avz -e "ssh -p 2222" app-v1.3.tar.gz deploy@192.168.1.100:/home/deploy/ - 删掉目标旧包再传(模拟“覆盖”语义):
rsync -avz --remove-source-files -e "ssh -p 2222" *.tar.gz deploy@host:/home/deploy/ - 注意
rsync路径末尾斜杠含义:/src/表示同步内容,/src表示同步目录本身 - 如果目标磁盘空间紧张,加
--dry-run先预览实际传输量











