我可以将一台服务器上的stdout传送到另一台服务器上的stdin吗?


74

stdout一台CentOS服务器上的管道需要通过管道传输到stdin另一台CentOS服务器上。这可能吗?

更新资料

ScottPack,MikeyB和jofel都有有效答案。我把答案授予了Scott,因为即使我的问题并未将安全性指定为要求,但安全总是很高兴的。但是,其他两个研究员的建议也将起作用。


1
值得注意的是,非ssh方法的(唯一)主要优点是吞吐速度。如果您使用的是快速网络并且不需要安全性,那么在两个窗口中键入两个命令可能会带来额外的不便。
Random832

Answers:


94

这是一成不变的。

当人们用来ssh在远程服务器上执行命令时,它会执行某种形式的内部输入/输出重定向。实际上,我发现这是OpenSSH更好的功能之一。具体而言,如果使用ssh一个远程系统上执行的任意命令,则SSH将映射STDINSTDOUT到该命令的执行。

出于示例目的,假设您要创建一个备份tarball,但是不希望或不能在本地存储它。让我们来看看以下语法:

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

我们正在创建一个tarball,并将其写入STDOUT常规内容。由于我们使用ssh来执行远程命令,标准输入被映射到STDINcat。然后我们将其重定向到文件。


11
那不是任何形式的“花哨的内部输入/输出重定向”,而只是普通的,无聊的常规内容。ssh像其他任何工具一样,从STDIN读取数据,并将其传递给远程进程。:)
Daniel Pittman 2012年

7
@DanielPittman:但是将其称为“内部花哨的”垃圾实在太有趣了。
Scott Pack

7
同样,netcat两端都提供了一个简单,易用的沟通渠道。tar cf - /path/to/dir | nc 1.2.3.4 5000在一个服务器上,nc -l -p 5000 > backupfile.tar在另一台服务器上。
MikeyB 2012年

1
@MikeyB:好点。Netcat是明文协议,因此请小心敏感数据。我倾向于将netcat用于更具体的事情,例如通过本地网络获取网络驱动器(ala dd)和端口扫描。
Scott Pack

2
@MikeyB:你们这些人,您的飞行和裤子就座!
Scott Pack

28

当您不必担心导线的安全性时,在主机之间管道传输数据的便捷方法是netcat在连接的两端使用。

这也使您可以异步设置它们:

在“接收器”上(实际上,您将进行双向通信,但这样想起来更容易),运行:

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

然后在“发送者”上运行:

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

很高兴知道。如果物理连接是受信任的(例如备用网络),或者连接已经建立了通道,则这很好。
韦斯利

或者,如果数据仍然是公开的。
塞缪尔·埃德温·沃德

1
+1 netcat是非常宝贵的工具,尤其是当您没有运行ssh服务器时。
沃里克2012年

21

用于创建单向和双向连接的功能非常强大的工具是socat。要简要了解各种可能性,请查看其联机帮助页中的示例。

netcat完全替代了类似的工具,并支持ssl加密连接。对于初学者来说,这可能还不够简单,但是至少知道它的存在是一件好事。


1
@WesleyDavid:在您的“更新”中:出于完整性考虑,我已经在回答中添加了socat具有SSL支持,因此也可以使用socat进行加密。但是,在大多数情况下,ssh是更好,更轻松的解决方案,因此,我也会选择ScottPack的答案。
jofel 2012年

5

TL; DR

当您拥有必须使用的堡垒服务器时,事情只会变得稍微复杂一些。

  1. 您可以像这样传递ssh命令ssh

    • cat local_script.sh | ssh -A usera@bastion ssh -A userb@privateserver "cat > remote_copy_of_local_script.sh; bash remote_copy_of_local_script.sh"
  2. 当心伪终端


请注意,这里ssh最重要的一点是,像大多数工具一样,默认情况下也只是对待stdoutstdin纠正。

但是,当您开始看到类似的选项时Disable pseudo-terminal allocation.Force pseudo-terminal allocation.可能需要进行一些反复试验。但是,通常来说,tty除非您试图修复终端仿真器中的乱码/二进制垃圾(人类输入的内容),否则您不希望更改行为。

例如,我倾向于使用-At以便转发工作站的ssh-agent,并确保远程运行tmux不会禁止二进制文件(例如ssh -At bastion.internal tmux -L bruno attach)。而且,对于docker而言(也是如此sudo docker exec -it jenkins bash)。

但是,-t当我尝试执行以下操作时,这两个标志会导致一些难以追踪的数据损坏:

# 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.

2

尝试仅通过一个命令将ssh公钥放入另一台主机

ssh root@example.com 'cat >> .ssh/authorized_keys' < .ssh/id_rsa.pub

2

我发现这是最简单的,在为您运行命令的用户在服务器之间未设置密码握手后:

未压缩

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

动态压缩

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

如果您ssh已经配置了压缩,那么在tar文件上使用压缩是一个非常糟糕的主意。
Anthon 2014年

@Anthon为什么如此糟糕,如何检查ssh压缩是否已启用?
汤姆·黑尔

1
@TomHale视您的系统速度而定,这可能会减慢整体操作,因为第二次压缩需要时间,但不太可能剃除其他字节。Compression可以在任何配置文件中进行设置,对此的快速检查是查看是否ssh -v localhost exit 2>&1 | fgrep -i compress提供任何输出(AFAIK没有选项,因为ssh已读入配置)。
Anthon

tar具有-C path适用于cx命令的标志。您无需cd在其中放置单独的命令。(但要注意,您可以运行多个命令。)
Bruno Bronosky

@Bruno,-C是GNU扩展(虽然现在还让bsdtar和席利焦油支持)
斯特凡Chazelas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.