9

Tip #552   Using ssh as a generic stdin consumer and stdout producer

Many people use netcat on both the remote and local machine in order to transfer stdin and stdout to and from machines over the network, but many don't realize you can do the exact same thing using one line with SSH:

ssh remote_machine 'cat - > file' < file


Of course that is useless since if you have ssh access, you can use scp or sftp, but what is more useful is inserting ssh anywhere in a pipeline to run a command on the contents on a remote machine. For example:

wget -O - http://ftp.mozilla.org/.../thunderbird-3.0b2-i686.tar.bz2 | ssh remote_machine 'tar xjvf -'


That will download the latest nightly build of Firefox 3.0 and extract it on remote_machine.

Of course, it works both ways:

ssh remote_machine 'wget -O - http://ftp.mozilla.org/.../thunderbird-3.0b2-i686.tar.bz2' | tar xjvf


That downloads Firefox on the remote machine and extracts it on the local machine.

That example is still kinda useless, but combine it with tee and command substitution, and you have a nice way to distribute the same tarball to multiple hosts:

wget -O - http://ftp.mozilla.org/.../thunderbird-3.0b2-i686.tar.bz2 \
| tee >(ssh host1 'tar xjvf -') | tee >(ssh host2 'tar xjvf -') | ssh host3 'tar xjvf -'


You can pretty much use ssh anywhere you want to send stdin to or receive stdout from remote machine commands. Using netcat sends everything in the clear, and if you have the access to run netcat, you probably have ssh access.