From: ara.t.howard@... Date: 2006-07-12T01:31:56+09:00 Subject: Re: Processes and Portability On Wed, 12 Jul 2006, Name Name wrote: > I would like to run a process concurrently (thus if the process goes to > sleep or runs forever, I can still run other code from my main process) and > have all standard out of that process be put into a text file. I would also > like this code to be portable. And finally, I would like to be able to kill > this process at any time (So I will need the pid) > > This thus eliminates the use of fork. Also, I have tried: > > a=IO.popen("program > logfile"), but on Windows this creates two > processes, cmd.exe and program. a.pid only gives the pid of cmd.exe. > And the behavior on *nix seems to be just the program (although I can be > wrong). > > So I require portability in that sense. > > Is this possible? > > thanks try this - i haven't tested on windows but it can certainly be made to work: harp:~ > cat a.rb #!/usr/bin/env ruby require 'rbconfig' require 'thread' class Spawn CONFIG = Config::CONFIG RUBY = if system('ruby -e 42') # ruby is in our path 'ruby' else # guess from rbconfig File.join CONFIG['bindir'], CONFIG['ruby_install_name'] end PROGRAM = "p $$;STDOUT.flush;STDERR.reopen(STDOUT);exec(*ARGV)" ATTRIBUTES = %w[ mutex out exitstatus exitstatus_q cmd pipe pid thread ] ATTRIBUTES.each{|a| attr_accessor a} def initialize *argv @mutex = Mutex.new @out = '' @exitstatus = nil @exitstatus_q = Queue.new @cmd = "#{ RUBY } -e '#{ PROGRAM }' #{ argv.join(' ') }" @pipe = IO.popen @cmd @pid = @pipe.gets.to_i at_exit{ Process.kill -9, @pid rescue nil } @thread = Thread.new{ begin while((line = @pipe.gets)) @mutex.synchronize{ @out << line } end ensure @pipe.close rescue nil exitstatus = $?.exitstatus @exitstatus_q.push exitstatus end } end def out @mutex.synchronize{ @out } end def exitstatus non_block = false @exitstatus ||= @exitstatus_q.pop(non_block) end class << self; alias [] new; end end require 'yaml' cmd = ARGV.join ' ' spawn = Spawn[ cmd ] y 'spawn.cmd' => spawn.cmd y 'spawn.pid' => spawn.pid y 'spawn.exitstatus' => spawn.exitstatus y 'spawn.out' => spawn.out harp:~ > ruby a.rb date spawn.cmd: ruby -e 'p $$;STDOUT.flush;STDERR.reopen(STDOUT);exec(*ARGV)' date spawn.pid: 27232 spawn.exitstatus: 0 spawn.out: | Tue Jul 11 10:31:22 MDT 2006 harp:~ > ruby a.rb no-exist spawn.cmd: ruby -e 'p $$;STDOUT.flush;STDERR.reopen(STDOUT);exec(*ARGV)' no-exist spawn.pid: 27235 spawn.exitstatus: 1 spawn.out: | -e:1:in `exec': No such file or directory - no-exist (Errno::ENOENT) from -e:1 regards. -a -- suffering increases your inner strength. also, the wishing for suffering makes the suffering disappear. - h.h. the 14th dali lama