lrzsz实战指南:rz/sz命令用法、原理与常见坑解析
2026/9/16 18:50:19 网站建设 项目流程

1. 为什么我还在用lrzsz这种“老古董”传文件

先说实话:我第一次用lrzsz的时候,内心是拒绝的。那时候我习惯用scp和sftp传文件,觉得命令行里有rsync、scp、sshfs这么多现代化工具,谁还用rz、sz这种看起来像是上个世纪的东西。直到有一次客户现场割接,服务器在带外管理的内网里,只有一台Windows跳板机,SSH能连但scp端口被封了,FTP更是想都别想,我整个人就傻在那儿了。

后面老同事甩给我两个命令——rz和sz,二十秒把文件传完了。那一瞬间我才反应过来:在很多真实的生产环境里,你根本不知道对方给你开了什么端口、装了什么服务,你唯一确定能用的就是一个SSH终端,甚至可能还是串口。这种场景下,lrzsz就是你最后的底牌。

lrzsz是一个经典的Unix/Linux串口文件传输套件,包含rz(接收文件,即从本地终端往服务器传)和sz(发送文件,即从服务器往本地终端下载)两个核心命令。它基于ZMODEM、YMODEM、XMODEM协议家族,通过标准的终端输入输出通道完成文件传输,不依赖网络端口、不依赖SSH服务端额外开洞,只要你能敲命令,它就能传文件。

现在很多刚入行的同事听到rz/sz的第一反应是“这不就是个Windows和Linux之间传文件的小工具吗”,这个认知不能算错,但严重低估了它的价值。在嵌入式开发、网络设备维护、服务器带外管理、内网隔离环境这些场景里,lrzsz经常是唯一能用的文件传输途径,甚至可以这么说:一个运维或者嵌入式工程师如果不会用lrzsz,在不少特殊环境里会寸步难行。

这篇文章我会把lrzsz的安装方式、核心用法、协议原理、常见坑和实战技巧一次性讲透,同时把我和它死磕多年总结出来的经验也一并放进去。无论你是刚接触Linux的新手,还是经验丰富的运维老手,这里应该都有你可能没注意到的细节。

2. 装好之前的准备工作:先搞清楚你的环境

lrzsz的安装其实非常简单,但安装之前有两件事必须先确认清楚,不然装完你也用不了,甚至可能把自己搞懵。

2.1 确认终端软件是否支持ZMODEM

这个点很多人会忽略,但恰恰是最关键的。rz和sz不是独立开一个通道去传文件,它们是往标准输入输出里塞数据,然后由终端软件负责把数据捞出来。Windows自带的cmd、PowerShell、老版本的Windows Terminal默认都不支持ZMODEM协议,你敲下rz命令后,终端会直接卡死或者乱码。

常用的终端软件支持情况我直接列个表,方便大家对照:

终端软件ZMODEM支持情况使用说明
Xshell内置支持弹窗提示文件选择,最省心
SecureCRT内置支持支持rz/sz协议重命名,稳定
MobaXterm内置支持上传下载都有图形化界面
FinalShell内置支持国产工具,双栏文件管理
PuTTY不支持需要搭配winscp等辅助工具
Windows Terminal默认不支持新版有插件但配置麻烦,不推荐
macOS Terminal不支持macOS建议用内置的scp或者iTerm2配合trzsz
iTerm2支持(需安装插件)配合trzsz-ssh插件使用

看到这儿你就明白了,与其说是Linux服务器上要装lrzsz,不如说是“服务器和终端两端配合”才能用起来。服务器端提供rz/sz命令以及ZMODEM协议的应答能力,终端软件负责弹出文件选择框、接收数据流、把收到的信息流转成文件。任何一端缺了,这事儿都成不了。

我个人的习惯是:服务器端装好lrzsz之后,第一件事永远是用一个已知支持ZMODEM的终端测试rz和sz是否通了,再交付给业务方。否则业务方用PuTTY连上去,敲个rz没反应,第一反应是找我来“修一下服务器”——其实服务器根本没毛病,是终端不支持。

2.2 常见发行版的安装命令

lrzsz在主流Linux发行版里都有官方软件包,用自带的包管理器装就行,不需要编译源码。这里我把常见发行版的安装命令整理一下:

# Debian / Ubuntu / Linux Mint 等 sudo apt update sudo apt install -y lrzsz # RHEL / CentOS 7 及以下 sudo yum install -y lrzsz # RHEL / CentOS 8+ / Rocky / AlmaLinux 等 sudo dnf install -y lrzsz # Fedora sudo dnf install -y lrzsz # openSUSE sudo zypper install -y lrzsz # Arch Linux / Manjaro sudo pacman -S lrzsz # Alpine Linux sudo apk add lrzsz

装完之后验证一下:

which rz sz rz --version sz --version

如果能正常打印出版本信息,说明安装成功。如果你用的是那种极度精简的发行版或者容器镜像,包里连包管理器都没有,那就只能走编译安装了。源码编译我也不展开太多,lrzsz的源码下载解压后就是标准的autotools三连:

wget https://www.ohse.de/uwe/re/lrzsz-0.12.20.tar.gz tar zxvf lrzsz-0.12.20.tar.gz cd lrzsz-0.12.20 ./configure --prefix=/usr/local/lrzsz make sudo make install sudo ln -s /usr/local/lrzsz/bin/rz /usr/local/bin/rz sudo ln -s /usr/local/lrzsz/bin/sz /usr/local/bin/sz

源码包里默认会编译出多个可执行文件,比如rz、sz、rb、sb、rx、sx等,它们不同的名字对应不同的传输协议,这个后面讲。对绝大多数人来说,用包管理器安装就够了,源码编译主要是为了应付那些连基础仓库都没有的离线环境。

2.3 一个容易忽略的细节:会话复用工具的影响

如果你习惯在服务器上用screen或者tmux,那我建议你在测试rz/sz之前先想清楚一个问题:你敲rz的时候,终端里有没有挂着screen/tmux会话?

为什么我要专门说这个?因为rxs/tmux这类终端复用器会拦截和重定向输入输出流,偶尔会把ZMODEM的传输数据搞乱。早期版本可能会有兼容性问题,我遇到过不少次在tmux会话里传文件,传到一半卡死或者文件损坏的情况。现在的版本大多能正常工作,但稳妥起见,第一次测试rz/sz时,建议先脱离screen/tmux,把它当作一个基准测试。如果脱离了就能正常传,在screen/tmux里传不了,那基本就是会话复用器设置的问题,不是你服务器的问题。

3. rz/sz的核心用法和参数,一次讲透

安装和验证都搞定了,接下来就是把rz和sz的日常用法彻底讲明白。注意这里是“讲明白”而不是简单“列参数”,因为我发现很多人用lrzsz只会裸敲一个rz,遇到稍微复杂点的场景就不知道怎么处理了。

3.1 rz命令:从本地上传文件到服务器

rz命令的作用是从本地终端往服务器传文件,最基础的用法是:

cd /path/to/upload/target rz

执行后,如果你的终端支持ZMODEM,会弹出一个文件选择对话框,选中你要上传的文件,确认后就开始传输。这里有三件事必须强调:

第一,先cd到目标目录,再敲rz。rz把文件收到哪儿,取决于你当前的工作目录。很多人习惯性在根目录或者家目录敲rz,回头找文件找不到,其实文件就在你敲命令时候所在的那个目录里。

第二,生产环境建议加-e参数。rz -e表示对传输内容做转义(escape),避免某些控制字符被误判。虽然现在绝大多数情况下不加-e也没问题,但在串口、老网络、特殊字符文件名这类场景下,加上-e能省掉一堆莫名其妙的传输损坏问题。

第三,-y参数控制同名文件覆盖行为。不加-y的时候,如果目标目录里已经有同名文件,rz会提醒你是否覆盖;加了-y就会自动覆盖,适合批处理场景。

我平时最常敲的命令是:

rz -ey

一句话解释:转义传输、同文件自动覆盖,最丝滑的组合。当然,如果你担心误覆盖重要文件,可以不使用-y

3.2 sz命令:从服务器下载文件到本地

sz命令是rz的反向操作,把服务器上的文件下载到本地。基本用法:

sz filename.txt sz /var/log/nginx/access.log

同样,下载到哪儿由你的本地终端设置决定。Xshell、SecureCRT这类软件默认会下载到一个固定的目录,一般在软件设置里可以改。我习惯把Xshell的下载目录设置成一个专门的D:\downloads\server文件夹,避免下载的文件和项目文件混在一起。

sz也支持批量下载:

sz file1.txt file2.txt /tmp/test.log

还可以用通配符:

sz /var/log/nginx/access.log.*

批量下载的情况下,终端软件一般会自动用日期或序号重命名文件,避免冲突。不同终端的命名规则略有差异,比如Xshell是自动加数字前缀,SecureCRT会弹出确认框。这个属于终端软件的行为,不归lrzsz管,没必要太纠结。

3.3 不要忘记还有rx、sx、rb、sb这几个兄弟

lrzsz包里其实包含多个命令,简单对应关系如下:

命令对应协议工作模式
rzZMODEM接收文件
szZMODEM发送文件
rxXMODEM接收文件
sxXMODEM发送文件
rbYMODEM接收文件
sbYMODEM发送文件

日常大家用rz/sz就足够了,因为ZMODEM是三个协议里最强大的一个,支持断点续传、批量传输、文件名保持、自动重传。XMODEM/YMODEM算是老前辈,协议简单、格式老,现在基本只有在老嵌入式设备或者老网络设备里才会碰到。

但懂他们的存在是有价值的。比如你在一台极其古老的设备上做维护,设备里只有rx/sx,这时候你要是连rx这个命令都不知道,可能就被卡住了。作为运维人员,命令不怕多记,关键时刻能救命。

3.4 嵌入式的例外:串口控制台上的lrzsz

嵌入式方向的朋友可能更关心串口场景。在串口控制台上,lrzsz也是可以用的,因为串口本质就是字符设备,ZMODEM协议通过标准输入输出就能跑。嵌入式Linux的busybox里一般也集成有lrzsz(通常以lrzlsz出现),用法一样。

但是串口场景下有两个额外的坑:

  • 波特率影响传输速度。115200波特率下实际传输速度大概是每秒11KB左右,传大文件会怀疑人生。为了保证传输成功,我一般先压缩再传,文件能小则小。
  • 流控要开。串口传输时终端软件的流控选项如果设置不对,大概率会传坏。建议硬件流控(RTS/CTS)关掉,软件流控(XON/XOFF)也关掉,ZMODEM协议自身有足够强的纠错能力,反而是流控选项容易干扰数据。

4. 从“能传文件”到“传得漂亮”:几个最实用的场景实战

工具本身不复杂,但这种工具类的东西,最大的价值不在于你记住了几个命令,而在于你知道在什么场景下怎么组合使用它。我挑几个这些年实际工作中用得最多的场景,完整过一遍。

4.1 场景一:Windows和Linux之间互传小文件

这是出现频率最高的场景。比如我在Windows上用Xshell连上一台CentOS服务器,需要把本地的jar包传上去部署,或者把服务器上的日志拉下来分析。

上传的完整操作是:

# 1. 到目标目录 cd /opt/app/deploy/ # 2. 执行上传,等待弹窗 rz -ey # 3. 弹窗后在Windows本地选中app.jar # 4. 确认上传,等待进度条完成

下载的完整操作是:

# 1. 找到要下载的文件 ls -lh /var/log/app/error.log # 2. 执行下载 sz /var/log/app/error.log # 3. 终端弹窗或直接默认路径保存到本地

这套组合拳打下来,整个文件传输过程不超过10秒,而且不需要额外开FTP服务、不需要装WinSCP、不用关心SSH端口是否映射到外网。

4.2 场景二:一堆服务器批量分发部署包

有一类场景是:你有一批服务器,每台都需要上传同一个安装包,但服务器之间不能直接互通,你只能通过跳板机逐台登录操作。一次性每台都敲rz然后选文件,其实效率也不高,因为还是得逐台手动确认。

这时候我的做法是:

  • 先把安装包用sz传到跳板机的一个固定目录
  • 然后通过跳板机用scp或者内网端口往目标服务器推

如果跳板机到目标服务器之间也走不了scp、只能通过SSH挨个登录,有个取巧的办法:

# 在每台目标服务器上都执行 cd /opt/setup/ rz -ey > /dev/null 2>&1 &

然后本地批量用SecureCRT的“传输文件”功能(它支持向多个会话同时发送ZMODEM文件),或者Xshell如果有批处理功能也可以。我实际测试下来,SecureCRT的批量传输更稳定。这个办法不依赖脚本,纯靠终端软件支持,适合不想在客户端装任何额外工具的团队。

4.3 场景三:超大日志片段按行截取下载

服务器日志动辄几个GB,直接sz整个文件,且不说终端软件会不会卡死,就算传下来也毫无意义——你只想要今天报错那一段。所以我的常规流程是:

# 先按行截取最近的500行 tail -n 500 /var/log/app/error.log > /tmp/error_20250120.log # 如果文件里有乱码,用iconv转一下编码 iconv -f UTF-8 -t UTF-8 -c /tmp/error_20250120.log > /tmp/error_20250120_clean.log # 压缩后下载 gzip -k /tmp/error_20250120_clean.log sz /tmp/error_20250120_clean.log.gz

为什么要把日志先gzip再下载?一是传得快,二是避免传输过程中因为编码、控制字符之类的因素把日志搞乱。-k参数保留源文件,省得传完发现还要再查一遍原始文件。

4.4 场景四:传输大文件时终端闪断,怎么办

大文件传输最烦的就是传到一半终端断了。ZMODEM本身支持断点续传,但前提是“同一个终端会话、同一个软件、同一个文件”才行。比如SecureCRT里传了一部分,软件卡死,你关掉软件重连,再敲sz传同一个文件,SecureCRT默认会问你是否续传。

Xshell我记得版本更新后也支持续传,但触发条件比较苛刻,不是百分百生效。如果遇到不支持续传的情况,最骚的操作其实是先压缩再传输,把文件拆成多个小块,分别传输:

# 把大文件拆成每个100MB的块 split -b 100M bigfile.tar.gz bigfile_part_ # 逐个下载 sz bigfile_part_aa bigfile_part_ab bigfile_part_ac # 本地合并 cat bigfile_part_aa bigfile_part_ab bigfile_part_ac > bigfile.tar.gz

这样即便某个块传输失败了,重新传那个块就行,不拖累其他文件。算是土办法,但在内网不稳定或者串口低波特率的环境下,比幻想ZMODEM自动续传靠谱得多。

4.5 场景五:自动化脚本里用lrzsz实现隐式交互

有一种场景是写运维脚本,希望用户在Windows本地选择文件上传到服务器,比如做一个自动部署脚本。传统方式下,脚本敲read命令从标准输入读路径是不行的,因为rz弹的是终端软件的文件选择框,不是终端文本输入。

但我们可以用交互式调用的方式,在Shell脚本里直接调rz,让它阻塞等待用户选文件:

#!/bin/bash echo "请在弹窗中选择需要上传的部署包:" cd /opt/deploy/ rz -ey if [ $? -eq 0 ]; then echo "文件上传成功" ls -lh /opt/deploy/ else echo "上传取消或失败" fi

lrzsz的命令退出码也是有用的:0代表成功完成,1代表用户取消或者传输失败。这样脚本可以基于退出码走不同的业务逻辑。我写过不少这种“人机交互式部署”的脚本,运维人员用起来很直观,不需要记任何受控命令,弹窗选文件就完事。

5. 那些年我用lrzsz踩过的坑,以及对应的排查思路

工具虽小,坑是真不少。我把这些年用lrzsz遇到的典型问题整理了一下,每个都附上排查链路和解决方案,希望能帮你少走弯路。

5.1 敲下rz命令后终端卡住,没有任何反应

这是最常见的问题,没有之一。遇到这种问题,先别急着怪服务器,按下面的顺序排查:

第一步:确认终端软件是否支持ZMODEM。如果你用的是PuTTY、Windows Terminal真机环境(不带插件),那基本可以断定是不支持,换Xshell/SecureCRT/MobaXterm即可解决。这是比例最高的原因。

第二步:确认服务器上是否装了lrzsz。执行which rz看有没有返回路径,没有就安装。有些精简镜像本身不带lrzsz,裸敲rz肯定没反应。

第三步:确认当前shell环境是否异常。有可能你的PS1变量里有特殊控制字符,导致ZMODEM握手失败。用bash --noprofile --norc进入干净环境再试一次,能通说明是shell配置的问题。

第四步:确认是否在tmux/screen会话里。退出tmux/screen再试,能通就说明是会话复用器的兼容问题。

第五步:看是否已经存在rz进程残留。如果上一次rz中断后没清理干净,可能导致新的rz命令卡住。执行pkill -9 rz清掉残留进程再试。

5.2 上传下载的文件内容不一致,或者文件损坏

文件传下来后,md5对不上或者解压报错,这是第二高频的问题。通常有以下几种原因:

原因一:传输过程中数据被终端软件转义或修改。尤其当文件的二进制内容含有某些特殊字节(比如Ctrl+C),并且你没有使用-e参数时,ZMODEM的转义机制和终端软件之间可能产生冲突。解决办法是统一使用rz -esz -e

原因二:使用了不支持二进制安全传输的老旧终端软件版本。某些老版本的终端软件对ZMODEM支持不完整,传文本还行,传二进制就损坏。升级终端软件到较新版本即可。

原因三:网络传输层存在问题,比如SSH连接不稳定、中间有网络设备丢弃数据包。这种情况下,ZMODEM虽然会重传,但如果断得过于频繁,最终也会失败。建议检查网络稳定性,或者改用更稳健的文件拆分传输方案。

原因四:串口场景下,流控配置不当导致丢字节。这个问题我在嵌入式章节说过了,检查串口软件的流控设置,同时建议加上-e

排查手段很简单:传完后在服务器端和本地分别执行md5sum,比对哈希值是否一致。凡是生产环境的重要文件,我强烈建议养成传输后校验的习惯。哪怕99%的概率没问题,校验一下又花不了几秒钟。

5.3 文件名中文乱码

服务器上文件名是中文,sz下载到本地之后文件名变乱码。这个问题出在“终端软件的编码设置”上,而不在lrzsz本身。lrzsz负责传输文件和文件名,但文件名到Windows本地之后怎么展示,是终端软件在管。

解决办法是:把终端软件的编码设置调整成和你服务器locale一致,或者统一用UTF-8。比如Xshell,在“文件->属性->终端->编码”里选UTF-8,SecureCRT也有类似的全局编码设置。如果服务器是老的CentOS 6系统且locale是POSIX或C,那建议把系统locale改成en_US.UTF-8,否则中文文件名在服务器侧本来就存储有问题。

另外一个更稳妥的办法是:传到本地之前先把文件名改成英文,例如:

cp 中文报告.pdf /tmp/report_20250120.pdf sz /tmp/report_20250120.pdf

我的习惯是,只要是跨系统传文件,文件名一律改成ASCII字符集——别小看这个习惯,能替你省掉大量后续处理麻烦。

5.4 传一半终端断线,重连之后文件不完整

这个坑我前面提过。ZMODEM理论上支持断点续传,但实际是否触发取决于终端软件。比如SecureCRT的断点续传做得相对成熟,重连后sz同一个文件,它会自动提示是否续传。Xshell的续传我记得也在新版本里加入了,但我个人测试结果不稳定,所以遇到重要文件传输,我不赌续传,直接用split拆块方案。

还有一个经验:传大文件之前,先用df -h看一下服务器磁盘空间是否足够,避免传到一半磁盘写满,导致文件损坏或rz直接失败。磁盘满这个因素我踩过不止一次,很冤。

5.5 用sz下载文件名带特殊字符的文件失败

文件名里有括号、空格、特殊符号,比如my file (final).tar.gz,直接用sz可能解析出问题。解决办法有两个:

最简单的办法是把文件复制或重命名为简单文件名再传:

cp "my file (final).tar.gz" /tmp/upload_final.tar.gz sz /tmp/upload_final.tar.gz

或者用引号包裹原文件名:

sz "my file (final).tar.gz"

这里面还有一个细节:sz支持的是多个文件参数,如果文件名以-开头,会被误认为参数,需要特殊处理。最稳妥的做法是先改名再加./前缀,比如:

sz ./-weird-name.txt

6. 进阶技巧:lrzsz在特殊场景下的几个关键操作

6.1 在容器环境里用lrzsz

容器里能不能用lrzsz?答案是可以,但有条件。如果你用的镜像太精简,比如busybox镜像里自带的lrz(busybox集成版)对ZMODEM协议支持得比较有限,最好还是装完整的lrzsz:

# 以Ubuntu基础镜像为例 apt update && apt install -y lrzsz

容器环境里需要注意的一个点是:rz/sz依赖标准输入输出是交互式TTY。如果你用docker exec进入容器,默认不分配TTY,rz会立即报错。需要用:

docker exec -it <container_id> bash

进入容器后再敲rz,才能正常工作。同理,Kubernetes里用kubectl exec -it进入Pod后,rz/sz也可以正常使用。这也是一个非常实用的场景——Pod里没装过SSH服务,也没有scp可用,但有kubectl exec就够传文件了。

6.2 用expect/shell脚本自动应答交互

理论上rz/sz都是交互式工具,需要人在弹窗里选文件。但有一种取巧的自动化思路是:本地预先用expect脚本模拟终端接受ZMODEM数据,从而绕过手动弹窗。这个方案偏小众而且折腾,我实际很少推荐,因为如果终端软件本身就支持ZMODEM,没必要自己造轮子。只有在你要写一个完全无人值守的传输脚本时才值得研究。

以Xshell为例,它支持一个命令行开关/z,可以把文件选择框变成命令行参数指定文件名,这样你可以写一个批处理脚本调用Xshell来完成自动传输。不过这属于Xshell的使用技巧,此处不展开。

6.3 调整传输超时和重试次数

lrzsz有一些环境变量可以调整传输行为,用得比较多的是:

# 设置超时时间(单位:秒) export ZMODEM_TIMEOUT=30 # 设置最大重试次数 export ZMODEM_RETRY=100

在极端不稳定的网络环境下,适当调大重试次数能明显提高传输成功率。在正常网络环境下,默认配置已经够用,不用动。

还有一个常用变量是ZMODEM_ESC_CTRL,它的作用和-e参数类似,控制是否对控制字符做转义。如果你发现-e在某些老终端上反而引发问题,可以试试这个变量。

6.4 和sftp/scp的取舍,什么时候该用lrzsz什么时候该用别的

这个话题想说的其实不是“谁替代谁”,而是“不同场景用不同工具”。我根据自己的经验画一个简单的选择路径:

  • 如果SSH服务正常、端口开放、网络通:优先用scp/sftp,或者rsync做增量同步,它们更快更稳,而且不需要终端软件配合。
  • 如果SSH能用但端口被防火墙限制、只有终端通道:用lrzsz。
  • 如果是串口终端、没有网络只有串口线:用lrzsz。
  • 如果需要远程批量同步几千个小文件:用rsync,lrzsz会传到你怀疑人生。
  • 如果是Windows跳板机上临时传个小文件到内网服务器的场景:lrzsz就是最快的路。

lrzsz不适合传超大文件,它本身走的是终端通道,效率上限受限于终端软件的接收能力和网络带宽。我见过有人拿它传几个GB的数据库备份,结果传了三天三夜还没传完。这类场景请老老实实开FTP或者开SCP端口,别跟工具特性较劲。

6.5 我用lrzsz搭建过的最舒服的一套部署流程

最后分享一个我目前用的比较多的小流程。我做Java后端部署时,多台服务器环境都预装了lrzsz,部署时就这样操作:

  • 本地用IDE打成jar包
  • Xshell连上跳板机,cd /data/deploy && rz -ey,弹窗选jar包
  • 脚本自动把jar包分发到各目标服务器,重启服务
  • 查看日志确认启动正常

整套流程从选文件到服务起来,应该也就一分钟左右。如果没有lrzsz,这个过程要么走FTP、要么让运维帮忙传、要么开SCP端口,效率完全不在一个量级上。

写在最后的体会

我早期对lrzsz有偏见,觉得它老、它土、它不现代,但这些年各种网络隔离环境跑下来,反而越来越觉得它能活这么多年是有道理的:它没有依赖任何复杂协议,没有要求你打开额外的服务端口,没有强迫你改变工作习惯,只要有一个能敲命令的终端窗口就行。这种“在最有限条件下解决最实际问题”的能力,其实挺值得反复品味的。

如果你看完这篇之后打算在服务器上试试,我建议第一次不要急着传大文件,先传一个小配置文件跑通流程,确认rz和sz都能正常交互,再应用到实际场景。另外记住两个习惯:一是上传前先cd到目标目录,二是rz -eysz -ey是你最好的朋友。等用到顺手了,你会发现这个“老古董”是真的香。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询