2013-08-30 24 views
2

我想运行一个shell脚本并捕获PID,STDERR,STDOUT和shell的退出状态。使用Ruby 1.8.7,我可以执行shell并捕获PID,STDOUT,STDERR,状态吗?

我使用的是Ruby 1.8.7,因此Open3没有获取PID的方法。我尝试过使用open4 gem,但不幸的是在写入过程中挂起几个脚本,手动运行时运行良好。

我想找一个替代品。您的指导将非常感谢!

+0

您可以通过Process.pid获取Ruby中的当前PID。让我知道如果这有助于 – Raghu

+0

谢谢Raghu,我正在寻找每个shell进程的PID产生,而不是当前进程的PID,对不起,如果我的写作误导你.. – Jay

+0

你可以发布一些示例代码,所以我们可以尝试重现这个问题? – iblue

回答

0

不幸的是,没有简单的方法来做到这一点。我试过PTY.spawn,但有时它会无法执行。如果你不能使用open3,那么你可以使用FIFO,但它有点混乱。下面是我在1.8.7上使用的解决方案:

# Avoid each thread having copies of all the other FDs on the fork 
def closeOtherFDs 
    ObjectSpace.each_object(IO) do |io| 
    unless [STDIN, STDOUT, STDERR].include?(io) 
     unless(io.closed?) 
     begin 
      io.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) 
     rescue ::Exception => err 
     end 
     end 
    end 
    end 
end 


# Utilities for fifo method 
require 'tempfile' 
def tmpfifo 
    # Use tempfile just to manage naming and cleanup of the file 
    fifo = Tempfile.new('fifo.').path 
    File.delete(fifo) 
    system("/usr/bin/mkfifo",fifo) 
    #puts "GOT: #{fifo} -> #{$?}" 
    fifo 
end 

# fifo homebrew method 
def spawnCommand *command 
    ipath = tmpfifo 
    opath = tmpfifo 
    #epath = tmpfifo 

    pid = fork do 
    #$stdin.reopen(IO.open(IO::sysopen(ipath,Fcntl::O_RDONLY))) 
    $stdin.reopen(File.open(ipath,'r')) 
    $stdout.reopen(File.open(opath,'w')) 
    #$stderr.reopen(File.open(epath,'w')) 
    $stderr.close 
    closeOtherFDs 
    exec(*command) 
    exit 
    end 

    i = open ipath, 'w' 
    #i.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC) # Doesn't work? Use closeOtherFDs 
    o = open opath, 'r' 
    #e = open epath, 'r' 
    e = nil 
    [o,i,e].each { |p| p.sync = true if p } 

    [o,i,e] 
end 

不是,它不干净。但是因为它使用fork并且处理三个句柄本身,那么你可以得到PID并完成open3的功能。

请务必在关闭文件句柄之后!这种清理后的产量版本可能会更有意义。

+0

作为一个说明,我有'closeOtherFDs'例程来查找和关闭所有stdin/stdout/stderr对象的原因是因为我如果你只是产卵了几个,那么你可以把这个代码拿出来 –

+0

而且,我刚刚意识到我粘贴的代码是关闭stderr,b你应该能够弄清楚如何使用tmpfifo。 –

+0

感谢@David Ljung Madison在帮助我的时候,我只是想保持简单,因为我有成千上万的过程被产生。无论如何,我已经使用反向执行的方式根据退出状态来移动输出。再次感谢!! – Jay

相关问题