【问题标题】:Is it possible to read the last line of STDOUT from an open process?是否可以从打开的进程中读取 STDOUT 的最后一行?
【发布时间】:2014-04-02 02:14:51
【问题描述】:

我正在使用 Stockfish 分析国际象棋位置,但具体的上下文并不那么重要。我想实时读取程序的输出,而不必等到进程完成。特别是我想阅读最后几行。目前我有:

require 'pty'

master, slave = PTY.open
read, write = IO.pipe
pid = spawn("stockfish", :in=>read, :out=>slave)
calculating=0 
slave.close
read.close

write.puts('uci')
write.puts("setoption name Threads value 1")
write.puts("position fen rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR")
write.puts('go infinite')

while calculating<10    
    sleep(1)
    master.each do |line|
        puts line
    end     
    calculating+=1      
end

write.puts('quit')
write.close

puts "done"

问题在于,直到所有 10 个循环都完成后,程序才会看到 EOF 标记,因此它会无限期地卡在 master.each 行块中。我可以使用master.gets 一次从开头读取下一行,但我将如何读取最后一行?

【问题讨论】:

  • 问题可能是 I/O 缓冲。如果stockfish 输出被缓冲,那么只有在缓冲区被写入、缓冲区被刷新或stockfish 终止时,您才会看到它。如果可能,请尝试禁用输出缓冲(必须在 stockfish 内完成)。
  • ruby 模块 PTY 负责处理。它创建了一个伪 shell,让 stockfish 认为我正在直接从 shell 运行所有内容
  • @kempchee 我不知道 PTY 模块。不错!

标签: ruby io pipe


【解决方案1】:

我现在有一个可行的解决方案:

fen="rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR"
overseer=fork do
  require 'pty'
  master, slave = PTY.open
  read, write = IO.pipe
  pid = spawn("stockfish", :in=>read, :out=>slave)
  slave.close
  read.close
  write.puts('uci')
  write.puts("setoption name Threads value 4")
  write.puts("position fen #{fen}")
  write.puts('go infinite')

  loop do
   puts master.gets     
  end   

end

if $stdin.gets
  Process.kill("KILL",overseer)
end

这将打印出一个流直到用户杀死它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-08
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多