
1. 为什么 MacBook 用户总在折腾传输文件这件事先说个我自己的场景笔记本上是 macOS服务器是各种 Linux 发行版Ubuntu、CentOS、Debian 都碰过日常要传代码、拉日志、备份数据库、丢配置文件。最早用 Mac 那会儿我还停留在“用网盘转一道手”的思维里——把文件传到某网盘再到服务器上另一台能联网的机器下载绕一大圈慢且容易出幺蛾子。后来发现macOS 自带的终端工具链其实完全可以覆盖绝大多数上传和下载场景只是很多人不知道选哪个、怎么用才稳。这篇博文就用实际操作为主把我在 MacBook 上往服务器传文件、从服务器拉文件的几种常用方案完整捋一遍。核心覆盖四类基于 SSH 的 scp、基于 SSH 的 rsync、交互式 sftp以及图形化工具兜底。如果你和我一样平时主要做开发、运维或服务器相关的事儿这篇文章能帮你少踩一些坑。哪怕你只是偶尔往云服务器传一个安装包照着步骤来也足够用。先提醒一句不管是哪种方案前提都是你已经有服务器 IP、账号、密码或密钥而且服务器的 SSH 服务默认端口 22是通的。底子没打好后面所有操作都白搭。2. 方案选型先搞明白该用哪种传输方式2.1 scp、rsync、sftp 到底有什么区别很多第一次接触这块的朋友容易犯迷糊同样是传文件为什么一会儿有人推荐 scp一会儿有人推荐 rsync还有人天天用 sftp其实它们背后都是走 SSH 通道但定位不同。scpSecure Copy最直接的文件复制工具适合一次性、小批量的上传或下载。命令短语法简单够用。rsync同步工具擅长增量传输。比如你本地有一个目录服务器上也有一个目录只想把“新增和改动过的文件”传过去rsync 是首选。对大目录、重复传输、断点续传场景非常友好。sftpSSH File Transfer Protocol交互式文件传输登陆之后像 FTP 一样敲命令支持浏览远端目录、逐文件下载。适合想要“一边看服务器上有什么、一边拉取”的场景在 Mac 的终端里直接敲 sftp 就能进。至于图形化工具比如 Transmit、Cyberduck还有通过 Finder 的“连接服务器”直接挂载本质上也大多走 SFTP 协议只是把命令变成了界面操作。2.2 为什么优先推荐“命令行优先”而不是一上来就用图形工具我在实际使用中体会最深的一点当你需要重复执行、写脚本、做定时任务时命令行工具的价值是图形工具完全没法比的。举个例子我每天凌晨要从几台服务器拉取业务日志回本地做分析用 rsync 一行命令配合 cron 就能定时跑而如果用图形界面这意味着我得每天手动打开软件点一遍。另外命令行工具天然跨平台。今天你在 MacBook 上会用了明天换到 Windows 的 PowerShell配合 OpenSSH依然有对应命令学习成本几乎为零。对从事开发、运维工作的人来说这是必会技能。2.3 图形化工具存在的意义当然不能一棒子打死图形化工具。遇到机器上没终端、需要可视化浏览目录、或者身边同事是不太熟悉命令行的普通用户客户端工具反而更高效。这部分我会在第 4 节专门展开给你一套可以“无脑操作”的方案。3. 核心实操scp 命令的完整使用指南3.1 先从最简单的开始单个文件上传scp 的基本语法是这样scp [选项] 源路径 目标路径把本地 /Users/你的用户名/Desktop/test.zip 上传到服务器 /root/ 目录命令是scp /Users/你的用户名/Desktop/test.zip root你的服务器IP:/root/回车之后会让你输入服务器密码如果你配置了密钥登录这步会跳过。传输过程会出现进度条类似这样test.zip 100% 12MB 12.0MB/s 00:01看到 100% 就说明传完了。这里有几个细节值得注意路径中有空格时要用引号包住例如scp /Users/你的用户名/Desktop/my file.zip root你的服务器IP:/root/默认端口不是 22 时需要加-P参数注意是大写 Pscp 和 ssh 的端口参数大小写不一样ssh 是小写 p别记混了如果本地当前目录就是文件所在目录可以省略绝对路径直接用./文件名代替3.2 下载文件到本地下载反过来写scp root你的服务器IP:/root/log.tar.gz /Users/你的用户名/Downloads/意思是从服务器的 /root/log.tar.gz 拉到本地下载目录。同样会显示进度条和速度。3.3 上传和下载整个目录如果是单个文件scp 够用了。但如果遇到目录就得加-r参数recursive递归复制scp -r /Users/你的用户名/代码工程 root你的服务器IP:/data/这个命令会把本地的“代码工程”整个目录复制到服务器的 /data/ 下。下载目录同理scp -r root你的服务器IP:/etc/nginx/ /Users/你的用户名/Desktop/nginx_bak/执行完之后本地桌面会多出一个 nginx_bak 文件夹里面是 /etc/nginx/ 的全部内容。3.4 为什么我后来很少用 scp 传大会话几个让人头疼的场景scp 简单归简单我实际用着用着就发现它的局限传输大目录、重复传输时每次都全量拷贝不做增量比较效率低。中断之后没有断点续传机制只能从头再来。传一个大文件传到 90% 断了真的想砸键盘。想要排除某些文件类型比如 .git 目录、.DS_Store 文件scp 没有直接的排除参数你得先压缩再传或者手动清理。需要保持文件属性权限、时间戳、owner时scp 的支持比较有限。所以当文件量变大、传输变得频繁时我就把主力切到了 rsync。接下来详细聊。4. rsync增量同步才是服务器传输的正确打开方式4.1 rsync 的核心逻辑rsync 的全称是 remote sync设计哲学是“只传输差异部分”。它的原理可以这样理解在传输前会先对比源端和目标端的文件列表只有新增的、大小变化的、修改时间变化的文件才会被传输完全没变的文件直接跳过。这带来的直接好处是第二次同步同一批文件时速度极快。比如一个 1GB 的目录第一次全量传输可能要两分钟第二次因为文件没变化瞬间就完成了。在 macOS 上使用 rsync 有个要注意的老问题系统自带的 rsync 版本可能比较旧macOS 自带的通常是 2.6.x而 Linux 发行版自带的多为 3.x。新旧版本在传输格式、参数上有些细微差别好在最常用的参数基本兼容。如果你经常和 Linux 服务器打交道建议用 Homebrew 装一个新版 rsyncbrew install rsync装完后可以通过rsync --version查看版本确认。4.2 使用 rsync 上传文件/目录上传目录的常用命令rsync -avz --progress /Users/你的用户名/本地目录/ root你的服务器IP:/远端目录/其中参数拆开来看-aarchive归档模式等于-rlptgoD的组合大致意思就是带上权限、属主、时间戳、符号链接等属性一起同步-vverbose显示详细信息列出每个同步的文件名-zcompress传输时压缩节省带宽--progress显示进度条命令执行后你会看到类似sending incremental file list file1.conf file2.txt sent 2,344 bytes received 48 bytes 4,784.00 bytes/sec total size is 12,345 speedup is 5.26这里“sending incremental file list”说明走的是增量逻辑只列出了这次实际有变化的文件。4.3 断点续传怎么实现这才是 rsync 真正的杀手锏。传大文件比如好几个 GB 的数据库备份传到一半 SSH 断了在 scp 场景下只能重新来过。但 rsync 加一个参数rsync -avz --progress --partial /Users/你的用户名/本地文件 root你的服务器IP:/远端目录/--partial的含义是保留部分传输的文件下次执行时基于已有进度继续传输。实测下来传一个 5GB 的文件第一次传了 3GB 断网恢复后再跑同样的命令只需要传剩下的 2GB。省时省心太多。4.4 排除不需要同步的内容在开发场景中本地目录往往有 node_modules、.git、.DS_Store 这类不需要同步到服务器的内容。rsync 提供了--exclude参数可以多次使用rsync -avz --progress --excludenode_modules --exclude.git --exclude.DS_Store /Users/你的用户名/项目/ root你的服务器IP:/data/项目/注意排除规则里的路径是相对于同步源目录的不需要写绝对路径。支持通配符比如--exclude*.log可以排除所有扩展名为 .log 的文件。4.5 下载目录并保留远端结构从服务器拉取整个目录到本地语法和上传一致只要调换源和目标的顺序rsync -avz --progress root你的服务器IP:/var/log/ /Users/你的用户名/Desktop/服务器日志/这个命令会把服务器上 /var/log/ 里的所有内容拉到本地的“服务器日志”目录。如果本地目录不存在rsync 会自动创建。4.6 容易踩坑的地方目录末尾的斜杠rsync 有一个非常多见、连老手偶尔都会翻车的点源目录后面加不加斜杠含义完全不同。rsync -avz /本地目录 root服务器:/远端/会把“本地目录”这个文件夹本身复制到远端rsync -avz /本地目录/ root服务器:/远端/会把“本地目录”里面的内容复制到远端区别就是加斜杠表示“目录内所有内容”不加斜杠表示“目录本身”。我第一次用 rsync 时想把本地项目同步到服务器命令写成了不加斜杠的形式结果在服务器上生成了 /远端/项目名/ 这样的嵌套目录后续部署脚本全乱了。从那以后我每次写 rsync都会在心里默念一遍“斜杠决定层级”并且执行前用--dry-run简写-n先演练一遍。4.7 推荐一个保险习惯先演练再真传rsync 的--dry-run参数可以在不实际传文件的情况下预览将要执行的操作。这个习惯可以帮你避开很多低级错误rsync -avz --dry-run /Users/你的用户名/项目/ root你的服务器IP:/data/项目/执行后只输出“如果真要同步会传哪些文件”不会产生实际的写入。确认无误后去掉--dry-run再真正执行。我基本养成了“每次写新 rsync 命令都先 dry-run 一遍”的习惯尤其是涉及删除操作时搭配--delete参数时更是必须演练。4.8 关于 --delete 参数的一个谨慎建议如果你希望让远端目录和本地目录保持完全一致本地删掉的文件远端也删掉可以加--deletersync -avz --delete /Users/你的用户名/项目/ root你的服务器IP:/data/项目/这个参数我一般建议新手慎用。因为一旦源端路径写错远端路径的正确文件很可能被一并删掉。如果你要用--delete请务必备份远端重要数据并且先用--dry-run确认删除的文件列表中没有“意外内容”。5. sftp交互式操作适合实时浏览远端目录5.1 一个命令直接进入 sftp 环境Mac 终端里输入sftp root你的服务器IP输入密码后进入 sftp 的交互式界面提示符变成sftp。在这个环境里你可以用命令浏览远端目录上传下载文件。5.2 sftp 常用命令速查我还真做过一个速查表贴在这里命令作用使用示例pwd查看远端当前目录pwdlpwd查看本地当前目录lpwdls列出远端目录内容ls -llls列出本地目录内容llscd切换远端目录cd /var/loglcd切换本地目录lcd Desktopput上传文件到远端put 本地文件.txtmput上传多个文件mput *.txtget下载远端文件到本地get 远端文件.txtmget下载多个文件mget *.logexit/quit退出 sftpexit5.3 实际场景演示拉取服务器日志假设我要查看服务器 /var/log/nginx/ 下有哪些日志文件并下载最近几天的访问日志。进入 sftp 后sftp cd /var/log/nginx sftp ls -l -rw-r----- 1 www-data www-data 12345 Dec 10 10:00 access.log -rw-r----- 1 www-data www-data 23456 Dec 10 09:00 error.log然后切换本地目录再下载sftp lcd /Users/你的用户名/Desktop/日志备份 sftp get access.log Fetching /var/log/nginx/access.log to access.log /var/log/nginx/access.log 100% 12KB 12.0KB/s 00:01如果你想下载错误日志并且想保留远端文件名直接sftp get error.log如果全部日志都要可以这样sftp mget *.log5.4 sftp 的局限sftp 适合临时性查看、小批量操作。但如果涉及大量文件、需要增量同步的场景sftp 就没有优势了。每次 get/put 都是单文件传输没有增量比较逻辑。所以我在实际使用中的分工是临时看个目录、传一两份配置用 sftp批量发布代码、服务器间同步、做备份用 rsync一句话就能搞定的单次文件复制用 scp6. 图形化工具不想敲命令时的兜底方案6.1 利用 macOS Finder 自带的“连接服务器”功能说实话很多人不知道 macOS 的 Finder 其实自带 SFTP 挂载功能不需要装额外软件。操作步骤打开 Finder按快捷键Command K在弹出的窗口中输入sftp://你的服务器IP点击“连接”输入用户名和密码连接成功后服务器根目录就像本地磁盘一样显示在 Finder 侧边栏可以直接拖拽上传或下载文件。这种方式适合小文件、不频繁的场景胜在零安装、零学习成本。不过它的限制也很明显传输速度不够稳定传输大文件时 Finder 偶尔会转菊花而且不支持断点续传和增量同步。6.2 第三方客户端Cyberduck 与 Transmit如果你的工作流是高频和服务器交互、又不想完全依赖命令行可以试试第三方 SFTP 客户端。Cyberduck 是免费的支持 SFTP、FTP、WebDAV跨平台macOS 上用得很顺手。下载安装后新建连接选择 SFTPSSH File Transfer Protocol填上服务器 IP、端口、用户名、密码双击即可连接。Cyberduck 还支持把远端目录保存为“书签”下次直接点开体验和本地文件管理器很像。Transmit 是收费软件但功能更强大。它的特点包括支持同时连接多个服务器可在面板之间直接拖拽传输支持 Transmit Disk可以把远程目录挂载到 Finder 中当作本地磁盘支持批量操作、队列传输与 macOS 系统集成度高右键菜单直接上传价格不算便宜但如果你每天都要和服务器文件打交道可能一天省下的时间就值回票价了。6.3 图形化工具什么时候该用、什么时候该回到命令行我得说句实话图形化工具虽好但很多自动化场景它替代不了。比如你要每天凌晨 2 点自动从服务器拉取备份到本地图形化工具很难做到。这时候 rsync cron 才是正解。我的使用习惯是传几个配置文件、改改远端目录内容用 Finder 挂载或 Cyberduck需要定时同步、增量备份、大批量部署命令行rsync服务器上目录结构不熟悉想黑盒探索一下用 sftp 或图形化工具一句话总结图形化工具适合“看得见、摸得着”的人机交互命令行工具适合“自动化、脚本化”的机器交互。两个都不冲突按需切换。7. 常见问题与排查技巧实录7.1 连接超时或 Permission denied这类问题排第一位的频率非常高。排查思路确认服务器 IP 有没有写错端口通不通本地终端执行nc -vz 服务器IP 22如果显示 connected 说明端口通确认 SSH 服务有没有启动在服务器上执行systemctl status sshd或service ssh status确认用户名和密码是否正确注意 Linux 用户密码默认不回显别以为键盘坏了如果服务器只允许密钥登录那你需要把本地公钥加到服务器的~/.ssh/authorized_keys里检查完还不行就看服务器的/var/log/auth.logDebian/Ubuntu或/var/log/secureCentOS里面会有详细的拒绝原因。7.2 传大文件速度慢、容易断没有万能的加速方案但有几个办法叠加起来效果明显优先用 rsync 加--partial断点续传加-z参数让传输时压缩文本类文件代码、日志、JSON压缩效果非常显著如果文件数量巨大比如几万个零碎小文件建议先在本地打包成一个 tar 压缩包再传传输速度会快好几倍服务器上 CPU 允许的话用-e ssh -C强制 SSH 压缩实际测试过一个包含 5 万个中小文件的目录rsync 直接同步耗时可能几十分钟还容易中断先打包成 tar.gz文件总数变成 1再传输全过程 5 分钟搞定。打包思路在传输大量小文件时永远有效。7.3 中文文件名乱码macOS 的文件系统APFS/HFS对中文文件名的编码方式和 Linux 服务器可能会有不一致导致传过去之后文件名乱码或者无法访问。这问题没有完美的代码级解释但可以从根源上规避在打包文件时先用英文命名规范整理一遍或者在 tar 打包时指定编码格式。如果是少数几个文件直接重命名再传是最省事的方案。如果你必须保留中文文件名实测下来 macOS 的 sftp 和 rsync 对 UTF-8 的支持效果相对好一些scp 偶尔会有问题。7.4 scp 命令不存在某些精简过的服务器系统可能默认没装 scp。这时候有两个选择服务器上安装 openssh-clientsCentOS或 openssh-clientDebian/Ubuntu改用 rsync如果服务器连 rsync 也没有需要安装 rsyncscp: command not found还可能出现在本地 macOS 上。这种情况很少见但如果出现排查/usr/bin/scp是否存在必要时通过xcode-select --install安装命令行开发者工具。7.5 权限问题Permission denied 却确定密码是正确的这种情况常见于 root 用户默认禁止 SSH 登录的服务器。很多云主机默认禁止 root 直接远程登录你需要先用普通用户登录再切换到 root。另外还要注意目录权限。假如你要上传到 /var/www/ 这个目录当前用户没有写权限也会报 Permission denied。解决办法先把文件传到 /tmp/ 或家目录登录服务器后移到目标目录或者调整目标目录属主/权限。7.6 防火墙和安全组问题使用云服务器时还有一个高频坑SSH 端口被安全组挡住了。云服务商的安全组规则和服务器本地的 ufw/firewalld 都要同时放行 22 端口或自定义的 SSH 端口。如果你改了 SSH 端口比如改用 2222那么传输命令中必须显式指定端口。scp 是-P 2222rsync 是-e ssh -p 2222rsync -avz -e ssh -p 2222 /本地目录/ root服务器IP:/远端目录/7.7 断点续传只对 rsync 有效别指望 scp这里再强调一遍因为我真的见过很多同事搞混。scp 和 sftp 都没有断点续传能力传大文件时一旦断开只能从零开始。rsync 的--partial才能保留已传部分。所以传大文件的黄金法则就一条别用 scp用 rsync。8. 实操总结搭建一个“一键同步”的日常方案8.1 具体需求我的日常需求是本地某个项目目录要同步到服务器上指定的发布目录同时从服务器拉取运行日志到本地备份。整个过程希望只输一条命令就完成全部操作。8.2 操作步骤先用 Mac 自带的“文本编辑”或 VS Code 创建一个 shell 脚本文件比如叫sync_server.sh内容如下#!/bin/bash # 配置区 SERVER_IP你的服务器IP SERVER_USERroot REMOTE_DIR/data/www LOCAL_DIR/Users/你的用户名/项目 BACKUP_DIR/Users/你的用户名/Desktop/服务器日志 echo 开始同步代码... rsync -avz --delete --excludenode_modules --exclude.git --exclude.DS_Store $LOCAL_DIR/ $SERVER_USER$SERVER_IP:$REMOTE_DIR/ echo 开始拉取日志... rsync -avz --progress $SERVER_USER$SERVER_IP:/var/log/ $BACKUP_DIR/ echo 全部完成保存后在终端里赋予执行权限并运行chmod x sync_server.sh ./sync_server.sh之后每次需要同步只需要进入脚本目录执行./sync_server.sh。如果你对这个脚本做了密钥登录配置整个过程连密码都不用输。8.3 配置 SSH 密钥免密登录如果你觉得每次输入密码很烦可以配置 SSH 密钥。在本地执行ssh-keygen -t ed25519 -C 你的备注一路回车即可生成的公钥在~/.ssh/id_ed25519.pub。然后把公钥内容追加到服务器的~/.ssh/authorized_keyscat ~/.ssh/id_ed25519.pub | ssh root服务器IP mkdir -p ~/.ssh chmod 700 ~/.ssh cat ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys之后再传输时就不需要密码了。这个操作建议做一次长期受益。9. 我从实际踩坑中总结的几条经验真正熟练之后你会发现这些工具本身并不复杂复杂的是在实际场景中的应变。这里把我反复踩坑换来的经验整理成几个核心要点供你参考。第一传大量零碎小文件前永远先考虑打包。文件系统对“数量”的敏感度远高于“总大小”几万个小文件会让传输效率暴跌还会增加 SSH 中断的概率。而把几万个文件变成一个 tar.gz 包传输效率能有数量级的提升。第二rsync 的 --delete 是一把双刃剑。它在保持两边目录一致的场景下确实好用但前提是你对源路径有十足把握。我在实际使用中养成了一个铁律带 --delete 的命令必须加 --dry-run 先跑一遍看到实际会删除的文件列表确认无误后才去掉演练参数执行。第三传输工具的选型与文件大小强相关。几个文件、几百 KB 的配置scp 足够几十 GB 的数据、需要断点续传rsync 是唯一稳妥选择临时浏览远端目录、想看看服务器上有什么sftp 顺手不想记命令的人图形化工具兜底。没有“最强大”的工具只有“最合适”的方案。第四别忽视文件名编码问题。跨系统传文件时中文文件名是最大的不确定因素。日常使用中我给服务器上的文件命名基本只用英文、数字、下划线这一条小习惯帮我少处理了非常多编码乱码问题。最后再分享一个小技巧可以在 macOS 的 shell 配置里给常用命令设置别名。比如在~/.zshrc中加入alias updatarsync -avz --progress --exclude.DS_Store ~/项目目录/ root服务器IP:/data/www/这样在终端输入updata就完成了代码发布简单直接效率很高。也希望你在折腾的过程中根据自己使用场景持续调整找到最适合自己的那套传文件节奏。