gpt4 book ai didi

ruby - 捕获从 Ruby 内部运行的交互式外部命令的输出

转载 作者:太空狗 更新时间:2023-10-29 12:22:58 25 4
gpt4 key购买 nike

我一直在寻找一种方法来运行交互式命令(例如 ssh)并捕获其输出。这听起来很简单,但据我了解,我的用例与许多 google 和 s/o 结果略有不同。

明确地说,我所说的交互是指从终端运行 my_ruby_script.rb 的用户应该能够

  1. 输入 (stdin) 正在运行的交互式系统命令(例如,通过 ssh 隧道输入 ls)
  2. 从 (stdout/stderr) 中读出正在运行的交互式系统命令(再次例如,在 中查看 ls 的输出>ssh 隧道)

最重要的是,我想读取系统命令 (ssh) 的输出,这样我就可以检查我的 Ruby 脚本中的错误。我得到的最接近的方法是简单地将输出 tee 到另一个文件。

system('ssh username@ssh_server |& tee ssh_log.txt')

这并不理想,因为

  1. 它需要保存到/从一个单独的文件读取
  2. 它需要一个更复杂的系统调用,它可能是可移植的,也可能不是可移植的

据我了解,大多数在线解决方案(反引号、Open3.*PTY.spawn() 等)都将 stdin/stdout 重定向到终端界面并进入ruby程序。我正在寻找的是单独留下 stdin,并将 stdout 连接到我的 Ruby 脚本。有人有什么想法吗?

我应该注意到 system('ssh username@ssh_server') 完全符合我的要求,我只需要能够读取输出。此外,我不希望使用 net-ssh 或任何其他非 stdlib 库。

研究:

  1. 这可能是描述 Ruby 中运行命令的最全面的页面(When to use each method of launching a subprocess in Ruby 和链接的博客文章)。
  2. 这些人有(在我看来)我完全相同的问题:
  3. 这些人通过 Ruby 使用 ssh 但他们的脚本不是“交互式”的

我非常感谢您提供的任何见解。

最佳答案

我找到了答案!非常感谢@Kimmo Lehto 提出了 IO.copy_stream() 想法,这导致了我的最终解决方案。基本上,我们使用 PTY.spawn(cmd){|stdin, stdout, pid| ...} 获取 stdinstdout 的无缓冲流。

然后我们用 IO.copy_stream($stdin.raw!, $stdin) 将脚本的 stdin 复制到命令的 stdin (don之后忘记设置 $stdin.cooked!)。

我不知道如何在命令的 stdout 上使用 copy_stream 两次(第一次到脚本的 stdout,第二次到缓冲区例如,io = StringIO.new) 所以我必须像这样手动读取每个字符:stdout.readchar(|c| print c; io.write c).

关于ruby - 捕获从 Ruby 内部运行的交互式外部命令的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52512537/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com