我一直在寻找一种运行交互式命令(例如ssh
)并捕获其输出的方法。听起来很简单,但据我了解,我的用例与许多google和s / o结果略有不同。
请注意,通过交互,我的意思是,从终端运行my_ruby_script.rb
的用户应该能够
stdin
)运行中的交互式系统命令(例如,通过ls
隧道键入ssh
)stdout
/ stderr
)中读取正在运行的交互式系统命令(例如,再次在ls
隧道中看到ssh
的输出)最重要的是,我想阅读系统命令(ssh
)的输出,以便例如从Ruby脚本中检查错误。我得到的最接近的结果只是将输出tee
简单地复制到另一个文件。
system('ssh username@ssh_server |& tee ssh_log.txt')
这不理想
据我了解,大多数在线解决方案(反引号,Open3.*
,PTY.spawn()
等)将stdin / stdout从终端界面重定向到ruby程序。我要寻找的是让stdin
独自一人,然后将stdout
放入我的Ruby脚本中。有人有什么主意吗?
我应该注意system('ssh username@ssh_server')
确实可以满足我的要求,我只需要能够读取输出即可。此外,我不想使用net-ssh或任何其他非stdlib库。
我非常感谢您可以提供的任何见解。
答案 0 :(得分:1)
我找到了答案!非常感谢@Kimmo Lehto提出了IO.copy_stream()
这个想法,该想法导致了我的最终解决方案。基本上,我们使用PTY.spawn(cmd){|stdin, stdout, pid| ...}
来获取stdin
和stdout
的未缓冲流。
然后我们用stdin
将脚本的stdin
复制到命令的IO.copy_stream($stdin.raw!, $stdin)
(不要忘了之后再设置$stdin.cooked!
)。
我无法弄清楚如何在命令的copy_stream
上两次使用stdout
(首先是脚本的stdout
,然后是缓冲区,例如io = StringIO.new
),所以我必须手动读取每个字符,例如:stdout.readchar(|c| print c; io.write c)
。