Robert La Ferla wrote:
> I'd like to run a system command and then stop it after specified amount
> of time (in seconds or milliseconds.)  What's the best way to do it?
> 
> e.g.
> 
> exec("cat /dev/video > test.mpg")
> 
> then kill the process after so many minutes, seconds, etc...

Once you call exec the ruby program does not run anymore.

From the description of Kernel#exec
http://www.ruby-doc.org/core/classes/Kernel.html#M005957

Replaces the current process by running the given external command. If
exec is given a single argument, that argument is taken as a line that
is subject to shell expansion before being executed.

you may want to use

system("cmd") http://www.ruby-doc.org/core/classes/Kernel.html#M005960
`cmd` http://www.ruby-doc.org/core/classes/Kernel.html#M005979
%x { cmd }

wrapped in timeout

> Also, if there is a better Ruby way to do this other than "cat", I'm all
> ears...

I'm using `mencoder ...` with options set via string substitution to
record TV-series

channel = ARGV[0]
outfilename = ARGV[1]
duration = ARGV[2]

`mencoder dvb://#{channel} -vf lavcdeint -o #{outfilename} -endpos
#{duration} -oac lavc -ovc lavc -lavcopts
acodec=mp2:vcodec=mpeg2video:vhq:vbitrate=2048`

If you want to read from '/dev/video' you could combine james.d.masters
and Dan Zwells suggestions - but using system or `

require "timeout"
begin
  Timeout::timeout(600) do
    system("cat /dev/video > test.mpg")
    # `cat /dev/video > test.mpg`
  end
rescue Timeout::Error
  puts("Done")
end

or

require "timeout"
begin
  Timeout::timeout(600) do
    File.open("/dev/video", "rb") do |input|
      File.open("test.mpg", "wb") do |output|
        input.each_byte {|byte| output.putc(byte)}
      end
    end
  end
rescue Timeout::Error
  puts("Done")
end

Stefan