linux ruby 获取ip地址,关于linux:捕获从Ruby内部运行的交互式外部命令的输出

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

很明显,我的意思是,从终端运行my_ruby_script.rb的用户应该能够

输入(stdin运行的交互系统命令(例如,通过ssh隧道的ls类型)

从(stdout/stderr中读出正在运行的交互系统命令(又如在ssh隧道中看到ls的输出)。

除此之外,我还想读取系统命令(ssh的输出,因此,例如,我可以从我的ruby脚本中检查错误。我得到的最接近的是简单的tee,输出到另一个文件。

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

这不是理想的

它需要保存到单独的文件/从单独的文件读取

它需要更复杂的系统调用,这可能是可移植的,也可能不是可移植的

据我了解,大多数在线解决方案(backticks、Open3.*和PTY.spawn()等)将stdin/stdout从终端接口重定向到ruby程序。我要找的是让stdin单独使用,并让stdout使用我的ruby脚本。有人有什么想法吗?

我需要注意的是,system('ssh username@ssh_server')完全按照我想要的做,我只需要能够读取输出。此外,我不希望使用net ssh或任何其他非stdlib库。研究:

这可能是描述在Ruby中运行命令的最全面的页面(何时使用Ruby中启动子进程的每个方法以及链接的博客文章)。

这些人(在我看来)有着完全相同的问题:

ruby io.popen或open3多写/读操作

https://www.ruby-forum.com/t/open3-and-ssh/147475

这些人通过Ruby使用ssh,但他们的脚本不是"交互式的"

从Ruby运行交互式程序

https://content.pivotal.io/blog/using-ruby-expect-library-to-reboot-ruckus-wireless-access-points-via-ssh

我真的很欣赏你所能提供的任何见解。

难道你就不能把stdout输出输入你的脚本中的用户吗?

(捕捉+分析后)

感谢您的回复!如果我能一个字符一个字符地读取命令的stdout以在终端中打印它(就像手动tee一样),这就可以了,但是我认为我不能这样做,因为输出将被缓冲。这在没有的线路(如jmate@ssh_server~$)时尤其有问题。

我认为通过popen3,你可以得到一个IO对象,你可以在没有缓冲或超时的情况下读取它。此外,您还可以执行类似于stdin.copy_stream($stdin)的操作。

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值