Sha256: 3e58ff162ddd5cdba179dd62ad1148d6bf595ab53a28ba092ce0cad2ee160bc8
Contents?: true
Size: 1.82 KB
Versions: 5
Compression:
Stored size: 1.82 KB
Contents
require 'pty' class PTYBackgroundProcess < BackgroundProcess # Runs a subprocess in a pseudo terminal, tricking a program into not # buffering its output. # # A great write up on pseudo-terminals here: # http://stackoverflow.com/questions/1154846/continuously-read-from-stdout-of-external-process-in-ruby # # It has the following disadvantages: # * You can't get the exit status # * When the process dies, whatever output you haven't read yet is lost. # * stderr is merged into stdout def self.run(command) thread = Thread.new do # why run PTY separate thread? When a PTY instance # dies, it raises PTY::ChildExited on the thread that # spawned it, interrupting whatever happens to be # running at the time PTY.spawn(command) do |output, input, pid| begin bp = new(pid, input, output) Thread.current[:background_process] = bp bp.wait rescue Exception => e puts e puts e.backtrace end end end sleep 0.01 until thread[:background_process] thread[:background_process] end def stderr raise ArgumentError, "stderr is merged into stdout with PTY subprocesses" end def wait(timeout = nil) begin Timeout.timeout(timeout) do Process.wait(@pid) end rescue Timeout::Error nil rescue PTY::ChildExited true rescue Errno::ECHILD true end end def exitstatus raise ArgumentError, "exitstatus is not available for PTY subprocesses" end protected def select_streams(which) case which when :stderr then stderr # let stderr throw the exception when :stdout, :both then [stdout] else raise(ArgumentError, "invalid stream specification: #{which}") end.compact end end
Version data entries
5 entries across 5 versions & 2 rubygems