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.
-
You can pass
sshas the command tosshlike so:cat local_script.sh | ssh -A [email protected] ssh -A [email protected] "cat > remote_copy_of_local_script.sh; bash remote_copy_of_local_script.sh"
- 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:latesexport or save filessh remote-hostssh to remote-hostcat - |read from STDIN and pipe itdocker import - alpine:latestread 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-hostssh to remote-hostdocker save getmeili/meilisearchrun this command<(CMD)redirect the output back to STDIN<read from STDINdocker import - getmeili/meilisearchread 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