你在服务器上跑完实验,生成了一堆结果文件,现在想拷到本地看看。或者服务器上有个项目目录,你想整个搬下来。
这件事听起来简单,但第一次做的时候总会卡在命令格式上。这篇文章讲三种方式:scp 直接拷 、先压缩再拷 、rsync 增量同步,从简单到高效,看完就能用。
一、先搞清楚一件事:方向
不管用哪个工具,核心格式都是:
命令 [从哪里] [到哪里]
从服务器拷到本地,"从哪里"就是服务器路径,"到哪里"就是本地路径。服务器路径的写法是:
用户名@服务器地址:远程路径
比如root@192.168.1.100:/home/data/results/,这个格式贯穿全文,记住就行。

三种方式都是"从服务器到本地"这一个方向,区别只在于传输策略:直接拷、压缩后拷、增量同步。
二、scp:最简单的拷贝
scp(Secure Copy)是基于 SSH 的文件拷贝工具,几乎所有 Linux/Mac 都自带,不需要额外安装。
2.1 拷贝用法
(1) 拷贝单个文件
例如,将服务器的 /home/data/result.csv 拷贝到本地当前目录。
bash
scp root@192.168.1.100:/home/data/result.csv ./
(2) 拷贝整个目录
加 -r(recursive,递归):
bash
scp -r root@192.168.1.100:/home/data/results/ ./results/
注意远程路径末尾的 /:加不加都行,scp 不敏感。但本地目标路径如果不存在,scp 会自动创建。
2.2 指定端口
如果服务器 SSH 不是默认的 22 端口:
bash
scp -P 2222 -r root@192.168.1.100:/home/data/results/ ./results/
注意是大写 -P,这一点和 ssh 的小写 -p 不一样。
2.3 scp 的局限
scp 够用,但有两个问题:
- 每次全量拷贝,1000 个文件改了 2 个,再 scp 还是传全部 1000 个
- 文件多了很慢 ,scp 是逐个文件建立传输的,文件数量多时开销大,即使每个文件很小。文件少的时候无所谓,但目录一大就该换方案了。
三、先压缩再拷:文件多的时候快很多
当目录里有成百上千个小文件时,先在服务器上打包压缩成一个文件,再 scp 拉下来 ,比直接 scp -r 快得多。
原因很直觉:传 1 个 100MB 的压缩包,比传 10000 个小文件快。因为省掉了逐个文件建立连接的开销,而且压缩后体积更小。

左边逐个文件传输,连接开销大、速度慢;右边打包成一个文件再传,一次连接搞定,体积还更小。文件越多,差距越明显。
3.1 完整流程
(1) 第一步:SSH 登录服务器,压缩目录
bash
ssh root@192.168.1.100
cd /home/data
tar -czf results.tar.gz results/
tar -czf 三个参数:c 创建归档、z 用 gzip 压缩、f 指定文件名。
(2) 第二步:回到本地,scp 拉压缩包
现在只有一个压缩包文件,传输很快。
bash
scp root@192.168.1.100:/home/data/results.tar.gz ./
(3) 第三步:本地解压
bash
tar -xzf results.tar.gz
x 是解压(extract),其他参数和压缩时一样。
3.2 一条命令搞定(进阶)
不想手动登录服务器?可以用 SSH 远程执行压缩,再管道直接拉下来:
bash
ssh root@192.168.1.100 "tar -czf - /home/data/results/" | tar -xzf - -C ./
这条命令做了三件事:远程压缩 → 通过 SSH 管道传输 → 本地直接解压。中间不落地临时文件。
-czf - 里的 - 表示输出到标准输出(而不是写文件),本地的 tar -xzf - 从标准输入读取,-C ./ 指定解压到当前目录。
3.3 压缩格式怎么选
| 格式 | 命令 | 压缩率 | 速度 |
|---|---|---|---|
.tar.gz |
tar -czf |
中等 | 快,最常用 |
.tar.bz2 |
tar -cjf |
较高 | 较慢 |
.zip |
zip -r file.zip dir/ |
中等 | 快,Windows 友好 |
日常用 .tar.gz 就行,压缩速度和压缩率的平衡最好。
3.4 别忘了清理服务器上的压缩包
拷完之后,服务器上那个临时压缩包可以删掉:
bash
ssh root@192.168.1.100 "rm /home/data/results.tar.gz"
四、rsync:只传有变化的部分
rsync 是 scp 的升级版。它会对比本地和远程的文件差异,只传输有变化的部分。第一次全量传,之后增量传,速度快很多。
4.1 基本用法
bash
rsync -avz root@192.168.1.100:/home/data/results/ ./results/
三个常用参数:
| 参数 | 含义 |
|---|---|
-a |
archive 模式,保留权限、时间戳、子目录等,最常用 |
-v |
verbose,显示传输过程 |
-z |
传输时压缩,网络慢的时候有用 |
4.2 远程路径末尾的 / 很重要
这是 rsync 和 scp 最大的区别,也是新手最容易踩的坑:
bash
# 末尾有 /:把 results 目录里的内容拷到本地 ./results/
rsync -avz root@server:/home/data/results/ ./results/
# 末尾没 /:把 results 这个目录本身拷过来,会变成 ./results/results/
rsync -avz root@server:/home/data/results ./results/
建议:源路径末尾加
/,这样行为更直觉:"把里面的东西同步过来"。
4.3 指定端口
bash
rsync -avz -e "ssh -p 2222" root@server:/home/data/results/ ./results/
4.4 排除某些文件
不想拷日志、缓存之类的:
bash
rsync -avz --exclude="*.log" --exclude="__pycache__/" root@server:/home/data/results/ ./results/
4.5 先预览,再执行
不确定会传哪些文件?加 --dry-run:
bash
rsync -avz --dry-run root@server:/home/data/results/ ./results/
它会列出将要传输的文件,但不会真的传。养成习惯,大目录同步前先 dry-run 看一眼。
五、怎么选
| 场景 | 推荐 | 理由 |
|---|---|---|
| 临时拷一两个文件 | scp | 最简单,不用想 |
| 目录里几千个小文件 | tar 压缩 + scp | 打包成一个文件传,快很多 |
| 大目录,之后还要反复同步 | rsync | 首次全量,之后只传变化的 |
| 想排除某些文件 | rsync | --exclude 很方便 |
| 服务器没装 rsync | tar + scp | 只依赖 SSH,哪都能用 |
一句话总结:偶尔拷用 scp,文件多先压缩,长期同步用 rsync。

以后再遇到"从服务器拷文件"的需求,顺着这张决策图走一遍,就知道该用哪个工具了。
六、实用补充
6.1 从本地传到服务器
把"从哪里"和"到哪里"调换位置就行:
bash
# scp
scp -r ./local_dir/ root@server:/home/data/
# rsync
rsync -avz ./local_dir/ root@server:/home/data/local_dir/
6.2 配合 SSH 配置简化命令
如果你在 ~/.ssh/config 里配了服务器别名:
Host myserver
HostName 192.168.1.100
User root
Port 22
那命令就可以简化成:
bash
rsync -avz myserver:/home/data/results/ ./results/
不用每次敲 IP 和用户名了。
6.3 传输大文件时想看进度
bash
rsync -avz --progress root@server:/home/data/bigfile.tar.gz ./
--progress 会显示每个文件的传输进度和速度。
七、总结
- scp 是最简单的远程拷贝,
scp -r拷目录,适合临时传几个文件 - 文件多的时候先压缩 :服务器上
tar -czf打包,scp 拉下来,本地tar -xzf解压 - rsync 是增量同步工具,
-avz三件套记住就行,长期同步场景首选 - rsync 的源路径 末尾加
/,避免多嵌套一层目录 - 大目录同步前用
--dry-run先预览 - 配合
~/.ssh/config可以大幅简化命令