摘要 :
scp是基于 SSH 协议的安全文件传输命令,无需额外配置即可在本地与服务器之间加密传输文件。本文从工作原理、基本用法(上传/下载/双服务器互传)、性能优化(压缩、限速、加密算法、断点续传替代方案)、密钥认证配置,到底层协议细节、与 rsync/sftp 的对比,以及常见问题排查,全面覆盖 scp 的日常使用场景,帮你高效、安全地完成文件传输任务。
日常开发中,我们经常需要在本地和服务器之间传文件。很多人习惯用 FTP 或者直接拖拽,但这些方式要么不安全,要么配置麻烦。scp(Secure Copy)可能是最简单也最靠谱的选择------它基于 SSH 协议,加密传输,一条命令搞定。
scp 的工作原理
scp 的本质是 SSH + 文件传输。它通过 SSH 协议建立加密通道,然后在通道上传输文件数据。
bash
┌────────┐ SSH 握手 ┌────────┐
│ 本地 │ ────────→ │ 远程 │
│ │ ←──────── │ │
│ │ 加密数据 │ │
│ │ ────────→ │ │
└────────┘ └────────┘
整个过程分三步:
- SSH 握手:协商加密算法、交换密钥
- 认证:密码或密钥认证
- 数据传输:文件数据在加密通道中传输
因为走的是 SSH,所以你服务器上能 SSH 登录,就能用 scp 传文件,不需要额外装任何东西。
基本用法
从本地传到远程
bash
# 传单个文件
scp /local/path/file.txt user@remote:/remote/path/
# 传整个目录(加 -r 参数)
scp -r /local/project/ user@remote:/remote/path/
# 指定端口(默认 22)
scp -P 2222 /local/file.txt user@remote:/remote/path/
注意:scp 的端口参数是大写 -P,不是小写 -p。小写 -p 是保留文件属性(时间戳、权限等)。这个坑很多人都踩过。
从远程拉到本地
bash
scp user@remote:/remote/path/file.txt /local/path/
# 拉整个目录
scp -r user@remote:/remote/project/ /local/path/
两个远程服务器之间传
bash
scp user1@server1:/path/file.txt user2@server2:/path/
这个用法有个细节:数据会先从 server1 下载到本地,再上传到 server2。如果你在本地机器上执行这条命令,带宽会走两次。如果两个服务器之间网络更快,可以 SSH 到其中一台再执行 scp。
性能优化:大文件传输技巧
传大文件时,默认参数可能不是最优的。几个实用技巧:
1. 启用压缩
bash
scp -C large_file.tar.gz user@remote:/backup/
-C 参数启用压缩。对于文本文件、日志等可压缩内容,能显著减少传输量。但如果已经是压缩格式(.gz、.zip、.mp4),再压缩反而会增加 CPU 开销,适得其反。
2. 限制带宽
bash
scp -l 10240 large_file.iso user@remote:/backup/
-l 参数限制带宽,单位是 Kbit/s。10240 Kbit/s ≈ 1.25 MB/s。这在共享网络环境下很有用,避免把带宽跑满影响其他服务。
3. 使用加密算法加速
SSH 默认用 AES-256-GCM 加密,安全性高但速度不是最快的。如果在内网传输,可以换用更快的算法:
bash
scp -c aes128-ctr file.txt user@remote:/path/
aes128-ctr 比 aes256-gcm 快不少,内网环境下安全性也够用。
4. 断点续传
scp 本身不支持断点续传,传到一半断了就得重来。这时候可以用 rsync 替代:
bash
rsync -avP --partial large_file.iso user@remote:/backup/
--partial 参数保留部分传输的文件,-P 等同于 --progress --partial。
密钥认证:告别密码输入
每次传文件都要输密码很烦。配置 SSH 密钥后可以免密:
bash
# 1. 生成密钥对(如果还没有)
ssh-keygen -t ed25519
# 2. 把公钥传到远程服务器
ssh-copy-id user@remote
# 3. 之后 scp 就不需要密码了
scp file.txt user@remote:/path/
ed25519 是目前推荐的密钥算法,比传统的 RSA 更短更快更安全。
底层实现:scp 的协议细节
如果你好奇 scp 底层怎么工作的,这里简单说一下。
scp 协议其实很简单,它复用了 SSH 的通道,在上面定义了一套文本协议:
bash
C0644 1234 file.txt
<文件内容>
C表示文件(directory 是D)0644是文件权限1234是文件大小(字节)- 然后发送文件内容
接收端解析这个头部,分配对应大小的缓冲区,接收数据写入文件。
这也是为什么 scp 传输大文件时内存占用不高------它是流式传输的,不需要把整个文件加载到内存。
scp vs rsync vs sftp
很多人搞不清这三个命令的区别:
| 特性 | scp | rsync | sftp |
|---|---|---|---|
| 增量传输 | ❌ | ✅ | ❌ |
| 断点续传 | ❌ | ✅ | 部分 |
| 交互式操作 | ❌ | ❌ | ✅ |
| 传输效率 | 一般 | 高 | 一般 |
| 使用场景 | 临时传文件 | 同步/备份 | 浏览远程文件 |
简单原则:传一两个文件用 scp,同步大量文件用 rsync,需要交互式浏览用 sftp。
常见问题排查
连接超时
bash
scp: Connection timed out
检查防火墙是否开放了 22 端口,或者用 -P 指定正确端口。
权限拒绝
bash
scp: Permission denied
确认远程目录有写权限,或者试试传到用户主目录 ~/。
传目录报错
bash
not a regular file
忘了加 -r 参数。传目录必须加 -r。
在线工具推荐
如果你只是偶尔需要查看 scp 命令的用法,或者想快速了解各种 Linux 命令的参数,可以试试在线工具:Linux 命令速查,上面收录了常用命令的语法和示例,搜索即用。
相关工具:SSH 安全远程登录 | rsync 远程同步 | wget 网络下载
