Last active
January 16, 2017 05:30
-
-
Save thewoolleyman/6a060574f22eafd42955812a1a2a7842 to your computer and use it in GitHub Desktop.
thewoolleyman-ruby-pty-check
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ruby-2.3.3 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/Users/woolley/.rvm/rubies/ruby-2.3.3/bin/ruby -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) /Users/woolley/workspace/gist-thewoolleyman-ruby-pty-check/pty_check_test.rb | |
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 83261 is running | |
PTY::check for process with pid 83261 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 83261 is running | |
PTY::check for process with pid 83261 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 83261 is NOT running | |
PTY::check for process with pid 83261 is : #<Process::Status: pid 83261 exit 0> | |
exitstatus: 0 | |
Process finished with exit code 0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 | |
return status | |
end | |
end | |
end | |
def wait_for_ready_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) | |
break if char.nil? # not sure why this is needed, but sometimes it is! | |
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 terminal_type_example | |
puts "\n\nterminal type example:" | |
cmd = 'echo $TERM' | |
puts "cmd: #{cmd}" | |
output_buffer = StringIO.new('') | |
PTY.spawn(cmd) do |r, w, pid| | |
wait_for_ready_to_read(r) | |
read_chars_to_output_buffer(r, output_buffer) | |
# 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_ready_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_ready_to_read(r) | |
read_chars_to_output_buffer(r, output_buffer) | |
# it's dead | |
process_running?(pid) | |
status = process_check(pid) | |
puts "exitstatus: #{status.exitstatus}" | |
end | |
end | |
output_only_example | |
invalid_command_example | |
terminal_type_example | |
input_output_example | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment