从服务器拷文件到本地:scp 与 rsync 实战

​ 你在服务器上跑完实验,生成了一堆结果文件,现在想拷到本地看看。或者服务器上有个项目目录,你想整个搬下来。

​ 这件事听起来简单,但第一次做的时候总会卡在命令格式上。这篇文章讲三种方式: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 可以大幅简化命令
相关推荐
云飞云共享云桌面2 小时前
SolidWorks三维设计不用单独买电脑,1台服务器10个设计用
运维·服务器·数据库·3d·电脑
acaad2 小时前
访问信创系统的服务器报错Received fatal alert: handshake_failure
运维·服务器
大树882 小时前
【无标题】
大数据·运维·服务器·人工智能
南境十里·墨染春水2 小时前
linux学习进展 基础命令 vi基础命令
linux·运维·服务器·笔记·学习
江畔何人初2 小时前
GTID的作用
linux·运维·服务器·mysql·云原生·kubernetes
今天又在写代码2 小时前
数据智能分析平台部署服务器
android·服务器·adb
茉莉玫瑰花茶2 小时前
mmap 文件映射 [系统加餐]
服务器
不愿透露姓名的大鹏3 小时前
MySQL Binlog配置优化全攻略
运维·服务器·数据库·mysql·adb
IMPYLH3 小时前
Linux 的 mkdir 命令
linux·运维·服务器·bash