Skip to content

Instantly share code, notes, and snippets.

@thewoolleyman
Last active January 16, 2017 05:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thewoolleyman/6a060574f22eafd42955812a1a2a7842 to your computer and use it in GitHub Desktop.
Save thewoolleyman/6a060574f22eafd42955812a1a2a7842 to your computer and use it in GitHub Desktop.
thewoolleyman-ruby-pty-check
input + output example - exits when given 'z' on STDIN:
cmd: ruby -e 'require "io/console"; while(i=$stdin.getch) do puts ">#{i}<"; if i == "z"; break; end; end'
Process with pid 80672 is running
PTY::check for process with pid 80672 is : nil
writing "a"
not ready to read, sleeping...
ready to read...
reading...
Read char '>' (ASCII 62) and wrote to output buffer
output_buffer contents:
>
reading...
Read char 'a' (ASCII 97) and wrote to output buffer
output_buffer contents:
>a
reading...
Read char '<' (ASCII 60) and wrote to output buffer
output_buffer contents:
>a<
reading...
Read char '' (ASCII 13) and wrote to output buffer
output_buffer contents:
>a<
reading...
Read char '
' (ASCII 10) and wrote to output buffer
output_buffer contents:
>a<
not attempting to read, not ready...
Process with pid 80672 is running
PTY::check for process with pid 80672 is : nil
writing "z"
not ready to read, sleeping...
ready to read...
reading...
Read char '>' (ASCII 62) and wrote to output buffer
output_buffer contents:
>a<
>
reading...
Read char 'z' (ASCII 122) and wrote to output buffer
output_buffer contents:
>a<
>z
reading...
Read char '<' (ASCII 60) and wrote to output buffer
output_buffer contents:
>a<
>z<
reading...
Read char '' (ASCII 13) and wrote to output buffer
output_buffer contents:
>a<
>z<
reading...
Read char '
' (ASCII 10) and wrote to output buffer
output_buffer contents:
>a<
>z<
not attempting to read, not ready...
Process with pid 80672 is NOT running
PTY::check for process with pid 80672 is : #<Process::Status: pid 80672 exit 0>
>a<
>z<
Process finished with exit code 0
#!/usr/bin/env ruby
require 'pty'
require 'io/wait'
def process_running?(pid, loop_until_not_alive = false)
loop do
Process.getpgid(pid)
puts "Process with pid #{pid} is running"
break unless loop_until_not_alive
sleep 0.5
end
rescue
puts "Process with pid #{pid} is NOT running"
end
def process_check(pid, loop_until_not_alive = false)
loop do
status = PTY.check(pid)
puts "PTY::check for process with pid #{pid} is : #{status.inspect}"
if loop_until_not_alive && !status
sleep 0.5
else
break
end
end
end
def wait_for_read_to_read(r)
loop do
unless r.ready?
puts 'not ready to read, sleeping...'
sleep 0.5
redo
end
puts 'ready to read...'
break
end
end
def read_chars_to_output_buffer(r, output_buffer)
loop do
unless r.ready?
puts 'not attempting to read, not ready...'
break
end
puts 'reading...'
char = r.read(1)
puts "Read char '#{char unless char.ord == 13}' (ASCII %3d) and wrote to output buffer" % char.ord
output_buffer.putc(char)
puts 'output_buffer contents:'
puts output_buffer.string
end
end
def output_only_example
puts "Simple output-only example:\n"
cmd = 'printf "f"'
puts "cmd: #{cmd}"
r, _, pid = PTY.spawn(cmd)
process_running?(pid) # Process is NOT running...
process_check(pid) # But STDOUT has not yet been read, so check returns nil
puts r.gets(1)
process_check(pid, true) # After STDOUT has not yet been read, check (soon) returns Process::Status
end
def invalid_command_example
puts "\n\ninvalid command example:"
cmd = 'exit 42'
puts "cmd: #{cmd}"
output_buffer = StringIO.new('')
PTY.spawn(cmd) do |r, w, pid|
sleep 0.5 # to give command time to run
# it will be dead by now
process_running?(pid, true)
process_check(pid, true)
puts output_buffer.string
end
end
def input_output_example
puts "\n\ninput + output example - exits when given 'z' on STDIN:"
cmd = %q(ruby -e 'require "io/console"; while(i=$stdin.getch) do puts ">#{i}<"; if i == "z"; break; end; end')
puts "cmd: #{cmd}"
output_buffer = StringIO.new('')
PTY.spawn(cmd) do |r, w, pid|
sleep 0.5 # to give command time to run
# it's alive
process_running?(pid)
process_check(pid)
puts 'writing "a"'
w.putc 'a'
wait_for_read_to_read(r)
read_chars_to_output_buffer(r, output_buffer)
# still alive
process_running?(pid)
process_check(pid)
puts 'writing "z"'
w.putc 'z'
wait_for_read_to_read(r)
read_chars_to_output_buffer(r, output_buffer)
# why isn't it dead?
process_running?(pid)
process_check(pid)
puts output_buffer.string
end
end
# output_only_example
# invalid_command_example
input_output_example
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment