ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Linux文件上传实战:scp、rsync与sftp完全指南

Linux文件上传实战:scp、rsync与sftp完全指南 前阵子一个刚转运维的朋友找我说他在云服务器上部署应用需要把一个离线安装包从本地传上去结果折腾了半天最后是打开微信发给自己再从服务器浏览器里登录微信下载的。这事听着离谱但确实反映了一个很普遍的问题很多人知道怎么用Linux也知道怎么操作服务器但“怎么把文件从本地上传到远程服务器”这一步始终是靠猜的。这篇文章我把日常工作中真正会用到、也真正稳定的文件上传方法完整梳理一遍。不只是给你命令还会讲清楚每种方式背后的适用场景、参数含义、容易踩的坑以及上传失败时怎么一步步排查。内容覆盖scp、rsync、sftp、图形化工具、Web面板、大文件断点续传、权限与安全底线这几个方向无论你是刚接触服务器的萌新还是已经在生产环境摸爬滚打的运维都能从中找到直接能用的东西。1. 先搞清楚传什么、传到哪里——不同场景下的上传思维1.1 “上传文件”这件事其实有四种完全不同的场景我见过太多人上来就问“用什么命令传文件”但很多问题恰恰出在场景没分清。同样是“上传”下面这些情况需要的方案完全不同本地机器传文件到远程Linux服务器。这是最常见的场景比如我要把自己电脑上的安装包传到云主机。核心工具就是scp、rsync、sftp这类基于SSH协议的命令行工具。远程服务器之间互相传文件。比如两台云主机要交换数据最常见的方式是在一台服务器上用scp或rsync直接推送到另一台这样不需要先下载到本地再上传。往服务器上的Web应用上传文件。比如网站后台需要接收用户上传的图片、文档。这种情况根本不是用scp而是通过应用自身实现的上传接口涉及的是后端逻辑和Web服务器配置。往树莓派、虚拟机、NAS这类设备上传。这些设备本质也是Linux系统但你可能没有公网IP只能在局域网内操作连接的细节比如端口、用户会稍微特殊。搞清楚自己属于哪种场景再往下选工具才不会出现“用ftp传了半天才发现服务器只开了22端口”这种尴尬。1.2 工具选型的底层逻辑安全优先能用SSH就不用别的做上传方案选型时我的判断顺序很固定SSH可用的情况下优先选基于SSH的工具。原因很简单绝大多数Linux服务器默认开启SSH你不需要额外安装任何服务端软件SSH通道全程加密文件内容和传输过程不会明文暴露权限体系和服务器上的用户体系天然一致你用什么账号登录上传的文件就属于哪个用户。很多教程会让你装vsftpd、配置FTP。但FTP有两个硬伤一是默认明文传输账号密码和文件内容都在网络上裸奔二是现在很多云厂商的安全组默认只放行22端口你要用FTP还得额外去开放21端口和数据端口增加了被扫描攻击的面。我的建议是除非有明确的合规或历史遗留需求否则直接放弃FTP方案不要在2025年还把一个带密码的明文协议架在公网上。还有一类方案是图形化工具比如FileZilla、WinSCP它们的底层传输协议走的还是SFTPSSH File Transfer Protocol本质上是给命令行工具套了一层可视化界面。这类工具适合文件数量多、路径层级深的场景操作效率比命令行高但你在服务器端需要保证sshd服务的Subsystem sftp是开启的。2. 命令行三件套scp、rsync、sftp的用法与边界2.1 scp最直接的一次性全量复制scpSecure Copy是SSH自带的远程复制命令用法和cp几乎一样只是目标地址从本地路径变成了“用户名主机:路径”。它的核心逻辑是把文件从A点完整复制到B点不做增量判断每次都是全量传输。最基本的几个用法# 单个文件上传 scp /path/to/local_file.tar.gz root192.168.1.100:/opt/ # 指定端口上传SSH端口不是默认22时 scp -P 2222 /path/to/local_file.tar.gz root192.168.1.100:/opt/ # 上传整个目录 scp -r /path/to/local_dir root192.168.1.100:/opt/参数说明-P必须是大写指定SSH端口-r递归复制目录-C开启压缩适合传文本类文件-i指定密钥文件。scp的最大优点是简单、无状态一条命令就完事。但它的缺点也很明显不支持断点续传。传输到一半网络断开对不起从头再来。不做增量校验。哪怕目标位置已经有同样的文件它也会全部重传一遍。scp命令本身在OpenSSH官方文档中已被标记为“deprecated”即将弃用因为它的实现比较老旧推荐用sftp或rsync替代。不过目前所有主流Linux发行版仍然支持它短时间不会消失。我现在的使用习惯是传一次性的小文件小于几百MB用scp图个快传大文件、频繁同步用rsync。2.2 rsync增量同步和断点续传的真正主力rsync是我个人最依赖的上传工具没有之一。它最大的价值在于增量同步传输前会对比源文件和目标文件的差异只传送发生变化的部分。这听起来复杂实际效果好得惊人。# 基础用法本地目录同步到远程 rsync -avz --progress /path/to/local_dir/ root192.168.1.100:/opt/remote_dir/ # 指定SSH端口 rsync -avz -e ssh -p 2222 --progress /path/to/local_dir/ root192.168.1.100:/opt/ # 断点续传--partial保留部分传输的文件 rsync -avz --partial --progress /path/to/big_file.tar.gz root192.168.1.100:/opt/参数含义这里必须逐个说清楚因为很多人用rsync出问题就是参数搞错了-a归档模式等价于-rlptgoD保留权限、时间戳、属主、组、软链接等属性。同步文件到服务器时几乎必加。-v显示详细信息。-z传输时压缩适合带宽受限或者传文本类文件。--progress显示传输进度和速率传大文件时一定要加。--partial保留部分传输的文件。如果不加这个参数rsync在上传中断后会删掉目标位置的半成品文件下次重新传。加上之后下次传输能基于已传的部分继续本质就是断点续传。--delete删除目标目录中源目录没有的文件。这个参数要谨慎用好了是同步利器用错了会误删数据。我建议新手先别加等完全理解它再考虑。还有一个特别容易踩的坑目录末尾的斜杠。# 带斜杠把local_dir目录下的内容同步到remote_dir/ rsync -avz /path/to/local_dir/ root192.168.1.100:/opt/remote_dir/ # 不带斜杠把local_dir这个目录本身同步到remote_dir/下 rsync -avz /path/to/local_dir root192.168.1.100:/opt/remote_dir/第一条命令如果remote_dir不存在它会创建一个然后把local_dir里的内容放进去第二条命令会在remote_dir下创建local_dir子目录再把内容放进去。这两条命令的目标路径结构完全不同生产环境中因为这个问题把文件同步错位置的情况太常见了我自己也踩过。2.3 sftp交互式操作最适合“一次传多个零散文件”sftp也是SSH协议家族的一员但它不像scp那样是纯命令行参数而是提供一个交互式界面。你连上服务器后像在本地终端里用cd、ls一样操作远程目录用put上传、get下载。# 连接 sftp root192.168.1.100 # 连接后执行命令如下 pwd # 查看远程目录 lpwd # 查看本地目录 lcd /path/to/local # 切换本地目录 cd /path/to/remote # 切换远程目录 put local_file.tar.gz # 上传文件 put -r local_dir # 上传目录 get remote_file.tar.gz # 下载文件sftp支持在交互模式中用reput恢复中断的上传相当于断点续传也支持lcd、lls这类本地命令操作。更实用的一点是它非常安全全程走SSH加密通道且无需在服务器上额外搭建任何服务。对日常操作来说sftp比scp多了一个“可交互”的优势你可以先连上去看看目标目录长什么样再决定传到哪里不会出现连路径都没确认就上传的情况。从自动化脚本的角度scp和rsync更合适因为它们能直接塞进shell脚本里跑而sftp的交互式特性不适合无人值守场景。2.4 三件套怎么选一张表说明白工具适用场景断点续传增量传输交互式操作自动化脚本友好scp一次性的小文件传输不支持不支持不支持非常适合rsync大文件、目录同步、长期备份支持--partial支持不支持非常适合sftp零散文件、需要人工确认路径支持reput不支持支持一般如果让我给一个最简单粗暴的选择建议**不确定用哪个的时候用rsync。**它几乎能覆盖所有场景只是命令比scp多几个参数但换来的是断点续传和增量同步这两个实打实的核心能力。3. 图形化工具与Web面板FileZilla、宝塔、网页终端到底怎么选3.1 FileZilla适合不习惯命令行的图形化方案FileZilla是一个免费开源的图形化FTP/SFTP客户端。它底层走SFTP协议时完全兼容Linux服务器的SSH服务。最容易被忽略的一个点是连接信息怎么填协议选择必须选SFTP - SSH File Transfer Protocol不是默认的FTP。端口填SSH端口默认22。如果你服务器改了端口这里填实际端口而不是21。登录类型用密钥认证选“密钥文件”并在下方选择对应的私钥文件用密码认证选“正常”。字符集连接Linux服务器时建议设置成UTF-8否则中文文件名容易乱码。FileZilla的优点是零学习成本左右分栏左边本地文件右边远程文件拖拽即可上传。缺点是如果你处理的文件路径很深拖来拖去反而不如命令行高效另外传大批量小文件时图形化界面的连接管理开销比较大速度会被限制。3.2 宝塔面板、1Panel这类管理面板适合服务器上跑业务的人现在很多服务器上装了宝塔面板或者1Panel这类可视化管理工具它们自带文件管理器可以直接在浏览器里上传文件到任意目录。这类面板的优势在于权限处理比较自动化。你在面板里上传文件它会自动帮你设置好owner和权限位基本不会出现“文件上传后网站读不了”的问题。对于非运维岗位的人来说是最省心的一条路。但必需说清楚它的不足面板本身是一个额外的Web服务暴露在公网上就多了一个攻击面。面板的登录入口一定要设置强密码并开启二次验证。上传大文件时走的是Web传输通道受Web服务器限制通常最大2GB且断点续传支持不如rsync稳定。面板文件管理器的底层其实是执行了类似mv、cp、chmod这样的操作操作过程中不会提示你目标目录大小、磁盘剩余空间这些信息传大文件前建议自己先看一下。如果你已经在用面板日常传配置文件、传小量业务文件完全没问题。但生产环境的大文件、正式版本发布包我还是推荐用rsync因为可控性更高出了问题也更容易排查。3.3 云厂商的网页VNC和Web终端应急可用别当主力很多云厂商控制台自带网页版VNC或Web终端这类工具的定位是应急救援通道比如服务器SSH连不上时可以通过网页终端登录。用网页终端配合rz命令确实能把本地文件传上去# 安装lrzsz yum install lrzsz -y # 或 apt install lrzsz -y # 输入rz命令会弹出文件选择框 rz # sz是下载把服务器文件拉到本地 sz /path/to/remote_file但这里有个非常具体的坑**网页终端和rz对终端类型有依赖很多云厂商的Web终端默认不是xtermrz会弹不出文件选择框或者上传到一半直接卡死。**我自己在几家主流的云厂商控制台都试过有的能用、有的不能用完全看运气。所以我的建议是网页终端可以用于救急平时不要依赖尤其是大文件绝对不要用rz传。4. 大文件、断点续传与任务中断rsync配合screen/tmux实战4.1 传输中断的克星--partial参数到底怎么工作传大文件最心疼的时刻是传了80%网络断了结果还得从头再来。rsync的--partial参数专门解决这个问题。它的工作机制是这样的rsync在传输过程中会把接收到的数据写入目标位置的临时文件。如果传输中断加上--partial之后临时文件不会删除。下一次执行相同命令时rsync会对比这个临时文件和源文件找出还未传输的块继续传。实操命令# 第一次传输中断也不要紧 rsync -avz --partial --progress big_file.tar.gz root192.168.1.100:/opt/ # 网络恢复后重复执行同样的命令即可继续 rsync -avz --partial --progress big_file.tar.gz root192.168.1.100:/opt/注意我加了--progress这个参数在传输时实时显示进度、速率和剩余时间传大文件时能让你心里有数不至于干等着不知道进行到哪一步了。4.2 用screen/tmux保住长任务SSH断开也不怕rsync虽然能做断点续传但有个前提你得重新登录服务器再执行一次命令。如果连续断网、反复重传体验仍然很差。更优雅的方案是提前用screen或tmux把rsync任务放在一个“永不中断”的会话里执行。# 新建一个名为upload的screen会话 screen -S upload # 在screen会话里执行rsync rsync -avz --partial --progress big_file.tar.gz root192.168.1.100:/opt/ # 按CtrlA再按Ddetach会话让任务在后台继续跑 # 重新连接 screen -r upload # 查看所有会话 screen -lsscreen的核心价值在于即使你的SSH客户端断开了screen会话里的任务仍然在服务器上运行。这相当于把上传任务“托管”在了服务器端本地断网不影响。tmux用法类似只是命令稍有不同# 新建会话 tmux new -s upload # 断开会话但不终止任务 # 先按CtrlB再按D # 重新附着 tmux attach -t upload # 列出会话 tmux ls这里有个经验之谈如果你要传的文件非常大比如几十GB建议把--partial和screen合起来用。万一服务器重启或者任务被意外kill掉有了--partial下次执行rsync可以从断点继续有了screen可以让你不用重头敲命令。4.3 大文件还可以先分卷再传关键命令我直接给出还有一种非常实用的场景上传通道带宽有限而且上传中断频繁。这时可以将大文件分卷压缩成多个小文件逐卷上传最后在服务器上合并。这个方法看起来笨但在某些特定网络环境下比断点续传更可靠。# 本地分卷归档每卷200MB tar czf - big_data_dir | split -b 200M - part_ # 将part_aa、part_ab等文件按顺序上传到服务器 scp part_* root192.168.1.100:/opt/ # 服务器上合并解压 cat part_* | tar xzf - -C /opt/这里split命令后面的-b 200M指定每卷大小part_是生成文件名的前缀。合并时cat part_*会按字母顺序拼接恢复出原始归档再用tar解压。这个方法在带宽窄、连接不稳定的场景下确实比任何断点续传方案都稳因为单个文件小传挂的概率低顶多重传一个小卷。4.4 关于并发加速不要盲目追求多进程有人会建议用多进程并发来加速传输比如同时跑8个rsync。这个方法在同一个服务器和同一带宽下效果极其有限因为瓶颈在带宽而不是连接数。盲目开多进程反而会让服务器内存和CPU承压。真正有效的加速路径是这些开压缩传输-z减少网络传输量换更快的网络链路用--bwlimit限制带宽占用避免上传任务把服务器带宽全占满影响线上业务。先把这几个做了再考虑并发的问题。5. 上传失败排查从端口到权限的完整链路5.1 一次真实的上传失败排查记录上个月帮同事排查一个rsync上传报错报错内容只有一行rsync: failed to connect to 192.168.1.100: Connection timed out (110)很多人看到这个报错第一反应是服务器挂了或者服务器上的SSH挂了。但如果你按下面的链路排查很快就能定位。第一步看网络是否通。ping 192.168.1.100 -c 4ping通说明网络链路没问题继续往下。ping不通问题在网络层检查IP、网关、安全组。第二步看SSH端口是否通。telnet 192.168.1.100 22 # 或者用nc测试 nc -vz 192.168.1.100 2222端口通了说明服务器上的sshd服务在监听不通可能是服务器sshd没起、防火墙拦截、或者安全组没放行22端口。那次排查的结果是22端口telnet超时。登录云控制台看安全组确认22端口规则还在再用网页VNC登录服务器执行systemctl status sshd输出显示sshd服务正常。继续看防火墙firewall-cmd --list-all # CentOS/RHEL # 或 ufw status # Ubuntu/Debian发现问题出在firewalld把22端口过滤了执行firewall-cmd --permanent --add-servicessh firewall-cmd --reload再测一次22端口通了rsync恢复正常。整个排查过程不到10分钟但如果不按链路走而是一次次重启sshd、重启服务器就完全是在浪费时间。5.2 上传到一半失败先查磁盘和目标路径的剩余空间还有一种非常常见的故障上传过程中提示No space left on device或者报错内容里包含write failed。这种情况大概率是磁盘满了。排查命令# 查看整体磁盘使用情况 df -h # 查看目标目录占用空间 du -sh /opt/upload_dir/ # 查看inode使用情况小文件多时会遇到inode耗尽 df -i注意df -i查inode这个点很多人会漏掉。当服务器上小文件极多时可能磁盘空间还有剩余但inode耗尽了同样无法写入任何新文件。5.3 Permission denied看懂权限位别乱用root上传命令执行后提示Permission denied (publickey,password)是另一类高频问题。这个提示有两层含义要么账号密码错误要么当前用户对目标目录没有写权限。先确认目标目录的具体权限ls -ld /opt/upload_dir/ # 输出示例drwxr-xr-x 2 root root 4096 Jan 1 00:00 /opt/upload_dir/这个目录只有root可以写。如果我用www用户上传就写不进去。解决方式有两种# 方式一把目录所属者改为当前用户 sudo chown -R www:www /opt/upload_dir/ # 方式二给目录增加写权限不推荐直接777 sudo chmod -R urwx /opt/upload_dir/我见过很多新手一上来就给目录chmod 777这是最糟糕的解法。777意味着所有用户都能读写执行等于把这个目录的门卸了。合理的做法是根据业务需要设置owner和group再配合最小化的权限位。5.4 SELinux也是“权限不足”的隐形元凶在CentOS/RHEL系列系统上还有一个容易被人忽略的因素SELinux。你明明给了正确的用户和权限上传也成功了但Web服务器就是读不了文件。这时很有可能是SELinux的上下文标签不对。# 临时关闭不推荐但可用于快速验证是否是SELinux问题 setenforce 0 # 如果你上传的是Web目录给文件打上httpd_sys_content_t标签 chcon -R -t httpd_sys_content_t /var/www/html/如果setenforce 0之后问题消失确认就是SELinux策略导致的。不要直接永久关闭SELinux修改/etc/selinux/config正确做法是找出正确上下文打上标签或者使用restorecon恢复默认上下文。6. 上传之外的安全底线校验、隔离与目录权限6.1 传完不等于完事校验文件完整性是最后一步文件上传到服务器后第一时间进行校验尤其是在生产环境部署版本包。校验方法很简单本地和服务器各算一次哈希值对比一致说明传输过程没有损坏。# 本地计算 sha256sum local_file.tar.gz # 服务器端计算 sha256sum /opt/uploaded_file.tar.gz对比两边输出的哈希值一致就放心了。如果希望更快可以用md5sum但md5在安全性上已经被突破更适合快速校验而非安全场景。有些人会把校验这一步省掉但我的经验是一旦文件在某次传输中损坏部署到生产环境后排查问题的成本远比提前花10秒校验要高得多。6.2 别用root账号直接传文件给业务建专属用户很多教程里的命令都直接用root方便是方便但隐藏风险不小。root账号权限太高一旦上传的脚本文件存在恶意内容执行后就等于给了攻击者完整的系统控制权。更合理的做法是为每个业务创建专属用户并把上传目录的所有权赋予该用户# 创建运维专用用户 sudo useradd -m -s /bin/bash deploy sudo passwd deploy # 把上传目录给deploy用户 sudo mkdir -p /opt/app_upload sudo chown -R deploy:deploy /opt/app_upload sudo chmod 750 /opt/app_upload这样上传入口隔离成独立用户即使出现安全问题攻击者也只能在该用户权限范围内操作。尤其多人协作时千万不要公用一个root账号出了问题无法定位责任人。6.3 上传目录也要防“二次被利用”这一点主要是给跑Web应用的读者提个醒。网站的文件上传功能在接收用户文件时必须对上传目录做一系列加固否则黑客上传一个恶意脚本到网站目录里通过Web直接访问就能执行形成经典的“文件上传漏洞”。几条实用的防护思路上传目录禁止执行脚本。以Nginx为例可以关闭该目录的PHP执行权限location ^~ /uploads/ { location ~ \.(php|php5|sh|py)$ { deny all; } }强制重命名上传文件。上传后不要让用户控制文件名而是由程序生成随机文件名避免用户上传.php文件后直接用原始路径访问。校验文件内容而不只是扩展名。很多“上传后门”是用图片马等方式实现的如果只校验扩展名很容易被绕过。更可靠的是用服务端库检测文件的真实类型MIME、文件头。上传目录不要放在Web根目录直接可访问的位置如果允许建议上传文件存储在Web根目录之外通过程序代理访问彻底断了脚本执行的可能。6.4 SSH层的基本安全配置密钥登录 禁止密码登录既然上传文件基本都是走SSH通道SSH本身的安全配置就不能松懈。最低限度的三件事用SSH密钥对代替密码登录。本地生成密钥对后把公钥追加到服务器的~/.ssh/authorized_keys中。确认/etc/ssh/sshd_config中允许密钥认证并考虑关闭密码登录PubkeyAuthentication yes PasswordAuthentication no关闭root直接SSH登录运维用户需要root权限时用sudo。这几项做完基本可以防止绝大多数针对SSH的暴力破解和密码扫描。改完之后记得systemctl restart sshd而且改配置时保持当前SSH连接不断开以免配置错误把自己锁在外面。几点实在的收尾建议写到最后分享几个我在实际项目中总结的个人习惯。如果你的目标只是“把文件传上去”scp最省事如果这个动作会反复出现rsync加部分参数是你最值得投资的工具。大文件传输前先看一眼服务器磁盘和网络带宽再决定用不用分卷。上传失败不要慌按照网络通畅性、22端口、sshd状态、防火墙、磁盘空间、目录权限、SELinux这个顺序排查基本能解决九成问题。还有一点很重要在正式服务器上操作前强烈建议先在本地虚拟机里把这些命令全部跑一遍。传错文件、误删数据这种事第一次发生最好是在自己的测试环境里而不是在客户的机器上。把这些基础的传文件技能练熟节省的不只是时间还有很多不必要的折腾。
返回列表