我可以将一台服务器上的标准输出通过管道传输到另一台服务器上的标准输入吗?

Wes*_*ley 87 pipe stdout stdin

stdout在一台 CentOS 服务器上需要通过管道连接到stdin另一台 CentOS 服务器上。这可能吗?

更新

ScottPack、MikeyB 和 jofel 都有有效的答案。我将答案授予 Scott,因为即使我的问题没有将安全性指定为一项要求,但安全总是好的。不过,其他两位研究员的建议也能奏效。

Sco*_*ack 116

这是一个毫不掩饰的肯定。

ssh在远程服务器上执行命令时,它会执行某种奇特的内部输入/输出重定向。事实上,我发现这是 OpenSSH 巧妙的更好的特性之一。具体而言,如果使用ssh一个远程系统上执行的任意命令,则SSH将映射STDINSTDOUT到命令的那个正在执行。

作为示例,我们假设您要创建备份 tarball,但不想或不能将其存储在本地。让我们看看这个语法:

$ tar -cf - /path/to/backup/dir | ssh remotehost "cat - > backupfile.tar"
Run Code Online (Sandbox Code Playgroud)

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

  • 这不是任何“花哨的内部输入/输出重定向”——只是普通的、无聊的常规内容。ssh 从 STDIN 读取,就像任何其他工具一样,并将其传递给远程进程。:) (13认同)
  • @DanielPittman:但称其为“花哨的内部”垃圾更有趣*。 (7认同)
  • 同样,两端的`netcat` 构成了一个非常简单、容易的通信渠道。`tar cf - /path/to/dir | nc 1.2.3.4 5000` 在一台服务器上,`nc -l -p 5000 > backupfile.tar` 在另一台服务器上。 (7认同)
  • @MikeyB:你们这些人怎么看你们的飞行和你们的裤子座椅! (2认同)

Mik*_*eyB 31

当您无需担心线路安全性时,在主机之间传输数据的一种便捷方式是netcat在连接的两端使用。

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

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

nc -l -p 5000 > /path/to/backupfile.tar
Run Code Online (Sandbox Code Playgroud)

在“发件人”上,运行:

tar cf - /path/to/dir | nc 1.2.3.4 5000
Run Code Online (Sandbox Code Playgroud)


jof*_*fel 21

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

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

  • @WesleyDavid:对于您的“更新”:为了完整起见,我在我的答案中添加了 socat 具有 SSL 支持,因此 socat 也可以进行加密。然而,在大多数情况下,ssh 是更好、更简单的解决方案,所以我也会选择 ScottPack 的答案。 (2认同)

Bru*_*sky 6

TL; 博士

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

  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.
Run Code Online (Sandbox Code Playgroud)