用scp跨服务器转文件夹,最简单的方式就是使用递归参数-r,一条命令即可完成整个目录的复制传输。
日常工作里,服务器之间的文件迁移是高频操作,不管是部署新项目、备份数据,还是迁移服务器环境,把整个文件夹从一个服务器搬到另一个服务器,scp是最直接、最不需要额外配置的工具,它基于SSH协议,安全性和稳定性都有保障,几乎所有Linux发行版都预装了OpenSSH客户端,开箱即用。
核心语法:scp递归复制文件夹
scp复制文件夹和复制文件的区别只在一个参数上-r,这个参数代表recursive(递归),告诉scp把目录下所有子目录和文件一并打包传输。
基础命令格式如下:
scp -r [本地目录路径] [用户名]@[目标服务器IP]:[目标路径]
举个例子,把本地服务器上的/home/user/www整个目录传到远程服务器168.1.100的/var/www目录下:
scp -r /home/user/www root@192.168.1.100:/var/www/
执行后会提示输入root用户的密码,输入正确密码等待传输完成即可,整个过程直观、无多余步骤。
从远程服务器下载文件夹到本地,则是把位置反过来:
scp -r root@192.168.1.100:/var/www/ /home/user/
这条命令会把远程服务器上的www文件夹整个拉到本地/home/user/目录下。
scp复制文件夹的完整参数清单
实际工作场景比基础命令复杂,服务器端口、密钥认证、传输速度都是常见变量,以下是scp传输文件夹时最常用的几个参数:
| 参数 | 作用 | 使用场景 |
|---|---|---|
-r |
递归复制整个目录 | 传输文件夹的必备参数 |
-P |
指定SSH端口(大写P) | 目标服务器SSH端口不是默认22时 |
-C |
启用压缩传输 | 传输大文件或网络带宽受限时 |
-l |
限制带宽占用 | 生产环境传输,避免影响业务流量 |
-i |
指定私钥文件 | 使用密钥登录,免密码输入 |
-v |
显示详细传输日志 | 排查连接问题 |
一个综合使用场景:公司服务器为了安全把SSH端口改成了2222,同时要求用密钥登录,传输时还要压缩数据,完整的命令长这样:
scp -r -P 2222 -C -i ~/.ssh/id_rsa /data/backup/ root@203.0.113.5:/backup/
指定端口复制目录的常见报错
很多人在加端口参数时容易踩坑,scp指定端口的参数是大写的-P,小写的-p是保留文件修改时间的参数,如果写了小写-p,SSH连接会默认走22端口,报错Connection refused。
另一个高频问题是目标目录不存在,scp不会自动创建多级不存在的目标目录,比如目标路径/var/www/html中的html目录不存在时,传输会直接失败,解决方案:先SSH登录远程服务器,用mkdir -p创建完整目录结构,再执行scp传输。
复制文件夹时路径末尾斜杠的细节差异
路径末尾是否加斜杠,决定了传过去的是文件夹本身还是文件夹里面的内容,这个细节在实际操作中容易混淆,但行业共识认为这恰恰是scp行为中最需要记清楚的一点。
- 本地路径末尾加斜杠,复制目录下所有内容到目标路径
- 本地路径末尾不加斜杠,连同目录本身一起复制过去
具体说明:执行scp -r /home/user/www root@server:/var/www/,传输到服务器后生成/var/www/www目录,执行scp -r /home/user/www/ root@server:/var/www/,传输到服务器后www目录下的内容直接放在/var/www/目录里。
远程路径末尾加不加斜杠,效果同理,这个细节对自动化脚本和批量部署尤其重要,写错路径层级会导致配置文件路径全部失效。
目录包含大量小文件时的传输优化
传输包含大量小文件的目录(比如Node.js的node_modules文件夹、前端构建产物、图片素材库)时,scp会逐个文件建立SSH连接通道,速度较慢,据统计,传输一个包含数万个小文件的目录,scp耗时可能是rsync的数倍。
优化策略分为两个层面。
先压缩再传输
把目录打包成单个压缩文件,传输完成后再解压,是传输海量小文件最高效的方式。
tar -czf www.tar.gz /home/user/www/ scp www.tar.gz root@192.168.1.100:/tmp/ ssh root@192.168.1.100 "tar -xzf /tmp/www.tar.gz -C /var/www/"
三步完成传输,压缩和解压消耗的CPU时间远小于逐个文件建立连接的开销,对于超过1GB的目录,这种方式优势明显。
使用rsync替代scp断点续传
网络不稳定时,scp中断只能从头传,rsync支持断点续传,传输大目录时容错性更好,需要确认远程服务器是否安装了rsync,绝大多数Linux发行版默认包含。
rsync -avz --progress /home/user/www/ root@192.168.1.100:/var/www/
-a归档模式保留文件权限和时间戳,-v显示过程,-z开启压缩。
scp和rsync的核心对比
日常工作中,不少人纠结选scp还是rsync,两者应用场景有明确边界,了解差异能帮助你在实际场景中做出合适选择。
| 对比维度 | scp | rsync |
|---|---|---|
| 传输方式 | 全量复制所有文件 | 增量同步,只传变化部分 |
| 断点续传 | 不支持 | 支持 |
| 文件属性保留 | 部分保留 | 完整保留(权限、时间戳、属主) |
| 传输速度 | 小目录无差异 | 大目录多次传输更快 |
| 安装依赖 | OpenSSH客户端即可 | 两端都需rsync |
| 适用场景 | 一次性迁移、简单传输 | 定时同步、持续部署、大数据量 |
一次性的整目录迁移,scp操作更简单直观;长期备份或者需要反复同步的场合,rsync效率更高。
权限与属主问题的处理
跨服务器传输文件夹后,经常遇到提示Permission denied无法读取文件,原因在于scp默认不保留原文件属主和权限组设置,文件属主变成执行传输操作的账号。
解决方案是在传输后通过SSH登录远程服务器,修改目录权限:
chown -R www:www /var/www/ chmod -R 755 /var/www/
www:www替换成实际需要的用户名和用户组,如果追求传输时直接保留原有权限,使用rsync -a参数能够完整保留文件属主、权限和时间戳。
无密码自动传输文件夹的配置方式
定时任务自动备份目录时,手动输密码不现实,配置SSH密钥免密登录后,scp命令就无需交互。
在本地服务器执行:
ssh-keygen -t rsa
ssh-copy-id root@192.168.1.100
ssh-copy-id会自动把公钥追加到目标服务器的authorized_keys文件中,之后执行scp命令,不再需要输入密码,这个配置同样适用于rsync和SSH登录。
crontab定时任务结合scp,可实现无人值守的跨服务器目录备份:
0 2 /usr/bin/scp -r /data/app/ root@192.168.1.100:/backup/app_$(date +\%Y\%m\%d)/
scp传输大文件夹时的性能考量
传输几十GB甚至上百GB的文件夹时,网络带宽成为瓶颈,默认情况下scp没有限速机制,会占满全部可用带宽,影响线上业务的正常响应,业内专家指出,生产环境执行大目录传输时,务必使用-l参数限制带宽上限。
scp -r -l 8192 /data/app/ root@192.168.1.100:/backup/
-l参数单位是Kbit/s,8192表示限速8Mbps左右,这个值根据实际出口带宽和业务容忍度来设定,宁小勿大。
启用压缩参数-C在文本类文件(代码、日志)为主的目录中效果显著,可以节省一半以上流量,对于已经压缩过的文件(图片、视频、压缩包),开启-C反而额外消耗CPU资源,收益不大。
目录名称包含空格的传输技巧
目标目录路径如果包含空格,比如/data/My Backups/,直接执行命令会报错,解决方案是在路径外面加双引号:
scp -r /data/app/ "root@192.168.1.100:/data/My Backups/"
双引号让scp把带空格的路径当作一个整体处理,本地路径包含空格时同理,也需要加引号包裹。
传输完整性校验方法
大文件夹传输完成后,无法直观判断所有文件是否完整,两个办法可以确认传输质量。
逐个比对文件数量和总大小:
ssh root@192.168.1.100 "find /var/www/ -type f | wc -l"
find /home/user/www/ -type f | wc -l
两边文件数量一致,基本可以判定传输完整,对完整性有更高要求时,计算MD5校验值:
tar -cf - /home/user/www/ | md5sum
ssh root@192.168.1.100 "tar -cf - /var/www/ | md5sum"
两个命令行输出的MD5值一致,文件完全相同。
常见问题排查清单
传输文件夹失败时,按以下顺序逐一排查:
- 确认源端目录存在且有读取权限:
ls -ld /path/to/dir - 确认目标端父目录存在且有写入权限:
ls -ld /path/to/parent - 确认SSH端口正确:
ssh -p 端口 用户名@IP - 确认防火墙放行端口:
firewall-cmd --list-ports或iptables -L -n - 确认目标目录空间充足:
df -h - 网络质量差时改用rsync配合断点续传
性能瓶颈汇总
多因素影响scp传输速度,瓶颈通常出现在单一一环,根据实际经验排序,对传输性能影响最大的因素依次是:网络往返延迟(大量小文件时RTT耗时占总时间比重大)、磁盘读写速度、CPU压缩负载(开启-C参数时)、MTU设置。
万兆网络环境下传输大型目录,磁盘速度往往成为最终瓶颈,可以考虑将源目录打包后再传输,减少IO随机读写的次数。
跨服务器文件夹传输的完整流程示例
从零开始,一个完整的跨服务器传输文件夹操作流程:
- 确认本地目录存在并确认大小:
du -sh /data/app - 确认远程目标父目录存在:
ssh root@目标IP "ls -ld /data" - 执行传输:
scp -r /data/app root@目标IP:/data/ - 查看传输后目录列表:
ssh root@目标IP "ls -l /data/app" - 核验文件数和大小:两边分别执行
find -type f | wc -l和du -sh - 修正权限和属主:
ssh root@目标IP "chown -R app:app /data/app"
这套流程覆盖了传输前检查、传输过程、传输后校验和权限修正的完整链路,适用于大多数生产环境场景。
Q&A:关于scp跨服务器转文件夹的高频疑问
scp传输文件夹时如何显示传输进度?
scp默认不显示进度信息,使用-v参数可以看到文件传输的详细日志,但这个输出对非技术用户不太友好,更直观的做法是使用rsync --progress或者rsync -P显示实时进度百分比和传输速率,如果坚持使用scp,-v参数查看速度信息,传输慢需要等待时使用-C参数压缩提速。
scp传文件夹中途断开了,能否续传?
scp本身不支持断点续传,中断后已传输的文件保留,重新执行命令会覆盖已存在文件,对于大目录传输,更稳妥的方案是分批次传输:先tar打包成多个分卷压缩包逐个传输,全部到达后再解压合并,这个方案对网络质量波动频繁的主机对传输场景尤其实用,是很多运维团队的替代方案。
本地Windows系统如何向Linux服务器传输文件夹?
Windows 10以上系统自带OpenSSH客户端,直接在PowerShell或CMD中执行scp命令,用法与Linux一致:
scp -r C:\Users\Admin\www root@192.168.1.100:/var/www/
路径采用Windows格式即可,更早版本的Windows系统,可以安装Git Bash或PuTTY套件中的pscp工具,如果服务器在简米云或酷番云上,也可以使用云服务商的网页版文件管理功能直接上传文件夹,操作更直观,但大批量文件传输的效率和稳定性通常不如命令行工具,上传后记得检查文件权限,Windows和Linux的权限体系不同,可能导致站点或服务无法正常读取文件。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/793287.html


