每天 SSH 到服务器上干活,难免要传个文件:把配置传上去,把日志拿下来。平时开一个 SFTP 工具就行,可有时它够不着:堡垒机登录后只给一个 shell,交换机接在串口线上,或者要连 ssh 好几跳才到目标机器。这时可以在服务器上敲 rz 上传、敲 sz 文件名 下载,文件直接从终端里传过去。这篇讲讲 rz、sz 是什么、怎么用,以及用不了时是怎么回事。
什么时候用得上
SFTP 和 scp 传文件,要在 SSH 连接里另开一条专门的通道,还要你的电脑能直接连到那台服务器。下面几种情况就做不到:
- 只给 shell 的堡垒机:登录后是一个菜单或受限的 shell,到目标机器的那一段由堡垒机代你连,SFTP 过不去。
- 串口控制台:交换机、开发板用串口线接在电脑上,两头之间只能来回传字符,没有网络。
- 多跳 ssh:在 A 上再
ssh B,从你电脑上发起的 SFTP 只能到 A。
这些时候,你和目标机器之间只剩一个终端:你敲的字传过去,屏幕上的字传回来。rz、sz 就借这条路传文件。
rz、sz 和 ZMODEM 是什么
rz 和 sz 是装在服务器上的两个命令,r 是 receive(接收),s 是 send(发送)。名字是从服务器这边说的,所以容易弄反:
| 在服务器上敲 | 服务器在做什么 | 对你来说 |
|---|---|---|
rz |
接收文件 | 上传:本机 → 服务器 |
sz 文件名 |
发送文件 | 下载:服务器 → 本机 |
命令总在服务器上敲,你的电脑这边不用运行什么,接另一头的是终端软件本身。rz 一启动,先往屏幕上输出一小段约定好的「暗号」,支持这个功能的终端认出暗号,就弹出选择框让你挑要上传的文件;sz 也一样,终端认出来后问你存到哪里。文件内容也混在终端的字符流里传过去。这和终端认出 OSC 转义序列 是一个思路:特殊的信号混在普通输出里,由终端挑出来。很多人用过的 Xshell、SecureCRT 都支持这个功能。
两头说的这套「话」叫 ZMODEM,是 Chuck Forsberg 在 1986 年设计的传文件协议。它出自用调制解调器拨号的年代,前面还有 XMODEM、YMODEM 两代。今天 Linux 上的 rz、sz 一般来自 lrzsz 这个软件包。
所以 rz、sz 能不能用,要看两头:服务器上装了 lrzsz,你用的终端支持 ZMODEM。
安装和使用
rz、sz 要装在服务器上。敲 rz 看到 rz: command not found,就是还没装:
sudo apt install lrzsz # Debian、Ubuntu
sudo dnf install lrzsz # RHEL、Rocky Linux、Fedora 等
sudo yum install lrzsz # 较老的系统
装好后,常用的就这几条:
rz # 上传:终端弹框选文件,可以一次选多个
rz -y # 上传,覆盖服务器上的同名文件
sz app.log # 下载一个文件
sz *.log nginx.conf # 一次下载多个
rz 默认不动服务器上已有的文件,遇到同名的就跳过,想覆盖要加 -y。sz 不能下载文件夹,会跳过它并提示 is not a file,可以先用 tar 打成一个包再下载:
tar czf logs.tar.gz logs/ && sz logs.tar.gz
rz 后屏幕上出现乱码
敲了 rz,没有弹框,屏幕上却多了一串怪字符:
$ rz
rz waiting to receive.**B0100000023be50
这就是前面说的暗号,原样显示了出来:你用的终端不支持 ZMODEM,或者没打开这个功能,另一头没人接。sz 时看到的是 **B00000000000000。文件没有坏,换一个支持 ZMODEM 的终端就好。
这时 rz、sz 还在服务器上等着,按 Ctrl+C 往往不管用,要连按 5 次 Ctrl+X,这是 ZMODEM 规定的取消方式。回到提示符后,如果打字显示不正常,输入 reset 再按回车。
tmux、screen 里用不了
tmux 和 screen 自己也是终端:它们先接住程序的输出,再重新画到你的窗口上。ZMODEM 的数据经过它们会被改掉,传输就失败或卡住。要传文件时,在 tmux 外另开一个连接运行 rz、sz,或者改用 SFTP、scp。
还要注意的几件事
- 单个文件不能超过 4 GB:协议只用 4 个字节记录文件里的位置,这就是上限。更大的文件可以用
split切开分别传,到本机再拼起来,或者用 SFTP。 - 中文文件名可能乱码:ZMODEM 不说明文件名用的是什么编码。服务器上的名字是 GBK、终端按 UTF-8 解读时,名字就乱了。传之前改成英文名,或者打包后再传。
- 隔着 ssh 上传时突然断线:在跳板机上再
ssh下一跳,或者在本地终端里用ssh命令连接时,上传的数据要经过这个 ssh 程序。ssh 把行首的~.当成「断开连接」,文件里恰好有这样的内容,连接就断了。连接时加上ssh -e none,就能关掉这个功能。
什么时候改用 SFTP、scp
rz、sz 胜在方便:不用另开工具,也不需要你的电脑能直接连到服务器,有终端就能传。但它的数据挤在终端这条路上:先经过服务器上的终端,再由你的终端软件一个字节一个字节地解出来;SFTP、scp 则走自己的通道。所以传大文件、很多文件或整个目录时,能用 SFTP、scp 就用它们;rz、sz 适合「只有一个终端、临时传几个文件」的时候。SFTP 和 WebDAV 有什么不同,可以看这篇文章。
在 ShellRS 里
ShellRS 是一个免费、开源的 SSH 客户端,支持 ZMODEM:
- 在终端里运行
rz或sz 文件名,ShellRS 自动接上。SSH、Telnet、串口终端都能用,只给一个 shell 的堡垒机上也行,在本地终端里 ssh 到别处再运行也行。服务器上要装 lrzsz。 - 上传:
rz弹出选择框,可以多选。也可以把文件从访达(Windows 上是资源管理器)拖到远程终端上,ShellRS 替你输入rz并回车,直接上传,不再弹框。文件夹会被跳过,请用 SFTP 上传。服务器上已有同名文件时显示「已跳过」,要覆盖请用rz -y。 - 下载:
sz每次都问存到哪个文件夹。下载不会覆盖本机已有的文件,同名时存成「名称 (1)」;没收完的文件会删掉。 - 传输时终端里有一行进度(文件名、百分比、大小、速度),按 Ctrl+C 取消。单个文件最大 4 GB,在 tmux、screen 里用不了。
详见 ShellRS 使用手册「终端」一章的「ZMODEM 传文件」,ShellRS 可以在下载页获取。