scp
is a great way to securely transfer files from computer to computer, but wouldn’t it be nice if you could just automatically send files over the existing SSH connection you’ve already opened?
Back in the days of modem-based BBSes and dial-up machine access, file transfers were forced to run over the same TTY as your interaction with the system. A number of different solutions evolved for this, starting with the grandfather of transfer solutions, XModem. Other transfer protocols evolved, some starting from the ground up like Kermit, while YModem and ZModem build on the foundation of XModem.
The latest version of iTerm 2 added support for two features that were very interesting: Triggers, that match a regular expression to a line of text; and co-processes, that can feed input directly into a terminal. With these two features, we can add the ability to stream files to and from any server over an existing ssh session. As ZModem is most modern protocol with wide support (lrzsz is well-supported and packaged on both OSX and Linux), I’ll show you how to use it to automate piggy-backed file uploads and downloads in your iTerm sessions.
Setup
First of all, install lrzsz
via brew. This will install the sz
and rz
binaries in /usr/local/bin/
:
macbook-pro-2:~ matthew$ brew install lrzsz
==> Downloading http://www.ohse.de/uwe/releases/lrzsz-0.12.20.tar.gz
==> ./configure --prefix=/usr/local/Cellar/lrzsz/0.12.20 --mandir=/usr/local/Cellar/lrzsz/0.12.20/share/man
==> make
==> make install
/usr/local/Cellar/lrzsz/0.12.20: 13 files, 376K, built in 21 seconds
Secondly, grab the scripts from my iterm2-zmodem github repo, and save them in /usr/local/bin/
.
Next, we’ll add a Trigger to your iTerm 2 profile that will trigger on the signature of the rz
and sz
commands. The setup for these commands differs based on the iTerm 2 version you have:
Build newer than 1.0.0.20111026
Regular expression: \*\*B0100
Action: Run Coprocess
Parameters: /usr/local/bin/iterm2-send-zmodem.sh
Regular expression: \*\*B00000000000000
Action: Run Coprocess
Parameters: /usr/local/bin/iterm2-recv-zmodem.sh
Build older than 1.0.0.20111026 (only receive supported)
Regular expression: [\$#] rz( -v)?$
Action: Run Coprocess
Parameters: /usr/local/bin/iterm2-send-zmodem.sh
Note: ideally we’d be matching on the ZModem initial packet signature: \*\*\u0018B01
in all versions of iTerm 2, but earlier versions of iTerm 2 had a bug that broke this pattern detection in this case. Instead we’re matching against the pattern of the rz
command typed at a shell for those older builds.
Receiving files from the server
To receive a file on your server, type the following at a shell prompt:
# rz
A file-picker dialog will then pop up asking you for the file to send. Once you choose the file to send, it will automatically transfer the file across your existing console session.
Sending files to the server
To send files from your server to your desktop, type the following:
# sz file1 file2 file3 /folder/file*
A folder picker will show up, asking where you want to drop the files. If you send multiple files, they will all appear in this folder.
Wrap-up
This is a pretty rough first pass at this, but the shell scripts are available on github if you’ve got ideas for improvement.
Follow me on Twitter: @mmastrac
Read full post