Can I pipe stdout on one server to stdin on another server?

stdout on one CentOS server needs to be piped to stdin on another CentOS server. Is this possible?

Update

ScottPack, MikeyB and jofel all have valid answers. I awarded the answer to Scott because, even though my question didn’t specify security as a requirement, it’s always nice to be safe. However, the other two fellows’ suggestions will also work.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

This is an unabashed yes.

When one uses ssh to execute a command on a remote server it performs some kind of fancy internal input/output redirection. In fact, I find this to be one of the subtly nicer features of OpenSSH. Specifically, if you use ssh to execute an arbitrary command on a remote system, then ssh will map STDIN and STDOUT to that of the command being executed.

For the purposes of an example, let’s assume you want to create a backup tarball, but don’t want to, or can’t, store it locally. Let’s have a gander at this syntax:

$ tar -cf - /path/to/backup/dir | ssh remotehost "cat - > backupfile.tar"

We’re creating a tarball, and writing it to STDOUT, normal stuff. Since we’re using ssh to execute a remote command, STDIN gets mapped to the STDIN of cat. Which we then redirect to a file.

Method 2

A convenient way of piping data between hosts when you don’t need to worry about security over the wire is using netcat on both ends on the connection.

This also lets you set them up asynchronously:

On the “receiver” (really, you’ll have two-way communication, but it’s easier to think of it like this), run:

nc -l -p 5000 > /path/to/backupfile.tar

And on the “sender”, run:

tar cf - /path/to/dir | nc 1.2.3.4 5000

Method 3

A very powerful tool for creating uni- and bidirectional connections is socat. For a short look at the possibilities, look at the examples in its manpage.

It replaces netcat and similar tools completely and has support for ssl encrypted connections. For beginners, it might be not simple enough, but it is at least good to know that it exists.

Method 4

TL;DR

Things only get slightly more complicated when you have a bastion server that must be used.

  1. You can pass ssh as the command to ssh like so:
  2. Beware of pseudo-terminals

Note that the point of key importance here is that ssh, like most tools, just treats stdout and stdin correct by default.

However, when you start to see option like Disable pseudo-terminal allocation. and Force pseudo-terminal allocation. you may need to do a little trial and error. But, as a general rule you don’t want to alter tty behavior unless you are trying to fix garbled/binary junk in a terminal emulator (what a human types in).

For example, I tend to use -At so that my workstation’s ssh-agent gets forwarded, and so that running tmux remotely doesn’t barf binary (like so ssh -At bastion.internal tmux -L bruno attach). And, for docker too (like so sudo docker exec -it jenkins bash).

However, those two -t flags cause some hard to track down data corruption when I try to do something like this:

# copy /etc/init from jenkins to /tmp/init in testjenkins running as a container
ssh -A bastion.internal 
ssh -A jenkins.internal 
sudo tar cf - -C /etc init | 
sudo docker exec -i testjenkins 
bash -c 'tar xvf - -C /tmp'

# note trailing slashes to make this oneliner more readable.

Method 5

Try to put your ssh public key in another host just by one command

ssh <a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e4968b8b90a4819c8589948881ca878b89">[email protected]</a> 'cat >> .ssh/authorized_keys' < .ssh/id_rsa.pub

Method 6

I find this to be the easiest, after setting up no password handshaking between servers for the user you are running the command as:

Uncompressed

tar cf - . | ssh servername "cd /path-to-dir && tar xf -"

Compression on the fly

tar czf - . | ssh servername "cd /path-to-dir && tar xzf -"

Method 7

For moving some docker images around, or VPN .conf files; sometimes I do this:

from local to remote

docker save alpine:latest | ssh remote-host "cat - | docker import - alpine:latest"
  • docker save alpine:lates export or save file
  • ssh remote-host ssh to remote-host
  • cat - | read from STDIN and pipe it
  • docker import - alpine:latest read from STDIN and save it

Then alpine:latest will be available on remote-host

from remote to local

docker import - getmeili/meilisearch < <(ssh remote-host docker save getmeili/meilisearch)
  • ssh remote-host ssh to remote-host
  • docker save getmeili/meilisearch run this command
  • <(CMD) redirect the output back to STDIN
  • < read from STDIN
  • docker import - getmeili/meilisearch read from STDIN

Then getmeili/meilisearch will be available on local host.

from remote to another remote (by help of a local)

cat - < <(ssh remote-host-1 "cat /home/pf/configs/shf.conf") | ssh remote-host-2 "cat - > /tmp/shf.conf"

In this style, I download shf.conf file from the remote-host (1) and without write it to desk sent it to another remote-host (2).

[ remote-1 ] => [ local (mypc)] => (remote-2)

Actually we can omit cat - < and use:

ssh remote-host-2 "cat - > /tmp/shf.conf" < <(ssh remote-host-1 "cat /home/pf/configs/shf.conf")

And this also sends newline if we be prompt for password , so the third version is better:

ssh remote-host-1  "cat /home/pf/configs/shf.conf" | ssh remote-host-2 "cat - > /tmp/shf.conf"


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x