> articles

How to use rz and sz to upload and download files in a terminal

When a terminal is all you have, rz uploads and sz downloads files with ZMODEM. What they are, how to install and use them, and what to do when they fail.

Published

On this page
  1. When you need them
  2. What rz, sz and ZMODEM are
  3. Installing and using them
  4. Garbage on the screen after rz
  5. It doesn’t work in tmux or screen
  6. A few more things to watch for
  7. When to use SFTP or scp instead
  8. In ShellRS

If you SSH into servers every day, sooner or later you need to move a file: a config file up, a log file down. An SFTP tool usually does it, but not always: the bastion host gives you a shell and nothing else, the switch sits at the end of a serial cable, or the machine is several ssh hops away. Then you can type rz on the server to upload, or sz filename to download, and the file travels through the terminal itself. Here’s how they work, how to use them, and what goes wrong.

When you need them

SFTP and scp open a channel of their own on the SSH connection, and they need your computer to reach the server directly. That rules out:

  • Bastion hosts that only give you a shell. You get a menu or a restricted shell, the bastion makes the onward connection for you, and SFTP can’t follow.
  • Serial consoles. A switch or a development board on a serial cable can only trade characters with your computer; there’s no network.
  • Multi-hop ssh. If you log in to A and run ssh B there, an SFTP session started on your computer ends at A.

In each case, all you have is a terminal: what you type goes over, and what the machine prints comes back. rz and sz move files along that same path.

What rz, sz and ZMODEM are

rz and sz are two commands on the server: r for receive, s for send. The names describe what the server does, so they’re easy to mix up:

Type on the server The server For you
rz receives files upload: your computer → server
sz filename sends files download: server → your computer

You type the command on the server and run nothing on your side; your terminal app is the other end. When rz starts, it prints a short, agreed-upon signal. A terminal that supports this spots it and opens a dialog for you to pick the files to upload; for sz, it asks where to save. The file itself travels mixed into the terminal’s stream of characters, the same idea as the OSC escape sequences that terminals pick out of ordinary output. Xshell and SecureCRT are well-known terminals that support it.

The language the two ends speak is ZMODEM, a file transfer protocol Chuck Forsberg designed in 1986, in the days of dial-up modems, as the successor to XMODEM and YMODEM. On Linux today, rz and sz usually come from a package called lrzsz.

So you need two things: lrzsz on the server, and a terminal that supports ZMODEM.

Installing and using them

rz and sz go on the server. If typing rz gives you rz: command not found, they aren’t installed yet:

sudo apt install lrzsz   # Debian, Ubuntu
sudo dnf install lrzsz   # RHEL, Rocky Linux, Fedora and the like
sudo yum install lrzsz   # older releases

After that, these are the commands you’ll use most:

rz                    # upload: the terminal asks for files, several at once is fine
rz -y                 # upload, overwriting files with the same name on the server
sz app.log            # download one file
sz *.log nginx.conf   # download several

By default, rz won’t touch files already on the server and skips an upload whose name is taken; add -y to overwrite. sz skips folders with is not a file, so pack one with tar first:

tar czf logs.tar.gz logs/ && sz logs.tar.gz

Garbage on the screen after rz

You type rz, no dialog appears, and a strange string shows up instead:

$ rz
rz waiting to receive.**B0100000023be50

That’s the signal, shown as plain text: your terminal doesn’t support ZMODEM, or has it turned off, so nothing on your side answers. With sz it’s **B00000000000000. Nothing is broken; a terminal that supports ZMODEM will do the job.

Meanwhile rz or sz is still waiting on the server, and Ctrl+C often does nothing. Press Ctrl+X five times instead, ZMODEM’s way of cancelling. If what you type doesn’t show properly once the prompt is back, type reset and press Enter.

It doesn’t work in tmux or screen

tmux and screen are terminals themselves: they take in a program’s output and redraw it in your window. ZMODEM data gets changed on the way through, so transfers fail or hang. To transfer a file, run rz or sz in a connection outside tmux, or use SFTP or scp.

A few more things to watch for

  • Files must be under 4 GB. The protocol records positions in a file with four bytes, and that sets the limit. Cut bigger files with split and join them afterwards, or use SFTP.
  • Non-English file names can come out garbled. ZMODEM doesn’t say how a file name is encoded, so names stored in, say, GBK on the server get mangled in a terminal that reads UTF-8. Give the files plain English names first, or pack them into an archive.
  • Uploads can suddenly drop through a chain of ssh. When you run ssh on a jump host, or in a local terminal, uploads pass through that ssh program, which takes ~. at the start of a line as “disconnect”. A file that happens to contain it cuts you off. Connect with ssh -e none to turn this off.

When to use SFTP or scp instead

rz and sz win on convenience: no extra tool, and no need for your computer to reach the server directly. But their data takes the long way round, through the terminal on the server and byte by byte through your terminal app, while SFTP and scp have channels of their own. For large files, many files or whole folders, use SFTP or scp when you can; rz and sz are for moving a few files when a terminal is all you have. For SFTP versus WebDAV, see this article.

In ShellRS

ShellRS is a free, open-source SSH client that supports ZMODEM:

  • Run rz or sz filename and ShellRS takes it up: in SSH, Telnet and serial terminals, on a bastion host that gives you only a shell, and in a local terminal where you ssh on to another machine. The server needs lrzsz.
  • Uploading: rz opens a picker where you can choose several files. Or drag files from the Finder (File Explorer on Windows) onto a remote terminal: ShellRS types rz and Enter for you and uploads them without asking. Folders are left out; upload those with SFTP. A file that already exists on the server shows as “Skipped”; use rz -y to overwrite.
  • Downloading: sz asks which folder to save into, every time. A download never overwrites a file: one with the same name is saved as “name (1)”, and a file not received in full is deleted.
  • A line in the terminal shows the progress (file name, percentage, size, speed), and Ctrl+C cancels. A file can be at most 4 GB, and transfers don’t work inside tmux or screen.

More in the ShellRS manual, under “ZMODEM transfers” in the Terminal section. ShellRS is available from the download page.

Try ShellRS

A free, open-source SSH client: terminals, SFTP and port forwarding in one window, for macOS, Windows and Linux.