Posted By

felipec on 05/18/07


Tagged

Shell Bash


Versions (?)

Who likes this?

1 person have marked this snippet as a favorite

webstic


Sheller


 / Published in: Ruby
 

Lets you run shell commands in an extensible way.

  1. class CommandError < RuntimeError
  2. end
  3.  
  4. class BaseCmd
  5. attr_accessor :uid, :done, :status
  6. end
  7.  
  8. class Sheller
  9. attr_accessor :continious
  10.  
  11. def initialize(bin = "bash")
  12. @sleep_time = 0.001
  13. @input_pipe = IO.pipe
  14. @output_pipe = IO.pipe
  15. @error_pipe = IO.pipe
  16. @invalid = false
  17.  
  18. fork do
  19. @input_pipe[1].close
  20. @output_pipe[0].close
  21. @error_pipe[0].close
  22.  
  23. $stdin.reopen(@input_pipe[0])
  24. $stdout.reopen(@output_pipe[1])
  25. $stderr.reopen(@error_pipe[1])
  26.  
  27. exec(bin)
  28. end
  29.  
  30. @input_pipe[0].close
  31. @output_pipe[1].close
  32. @error_pipe[1].close
  33. end
  34.  
  35. def low_write(data)
  36. printf "#{data}" if $DEBUG
  37. @input_pipe[1].write(data)
  38. end
  39.  
  40. def write(data)
  41. low_write(data)
  42. low_write("echo -e \"\027:$?\" > /dev/stderr\n")
  43. end
  44.  
  45. def poll
  46. clean = true
  47.  
  48. if svrs = IO.select([@output_pipe[0]], nil, nil, 0)
  49. svrs[0].each { |io|
  50. clean = false
  51. line = io.readline.chomp
  52. got_stdout(line)
  53. }
  54. end
  55.  
  56. if svrs = IO.select([@error_pipe[0]], nil, nil, 0)
  57. svrs[0].each { |io|
  58. clean = false
  59. line = io.readline
  60.  
  61. if line[0] == 23
  62. md = line.match(/^.:(\d+)$/)
  63. if md
  64. @pending_cmd.status = md[1].to_i
  65. raise CommandError if @pending_cmd.status != 0 && @continious
  66. end
  67. else
  68. got_stderr(line)
  69. end
  70. }
  71. end
  72.  
  73. if @pending_cmd.status and clean
  74. @pending_cmd.done = true
  75. end
  76. end
  77.  
  78. def read_loop
  79. while [email protected]_cmd.done
  80. poll
  81. sleep(@sleep_time)
  82. end
  83. end
  84.  
  85. def do(string)
  86. @pending_cmd = BaseCmd.new
  87. begin
  88. write("%s\n" % string)
  89. read_loop
  90. rescue EOFError,Errno::EPIPE => error
  91. Process.wait
  92. # $?.exitstatus
  93. @invalid = true
  94. return nil
  95. end
  96. return @pending_cmd
  97. end
  98.  
  99. def info(string)
  100. puts "# %s" % [string]
  101. end
  102.  
  103. def got_stdout(line)
  104. end
  105.  
  106. def got_stderr(line)
  107. end
  108.  
  109. end

Report this snippet  

You need to login to post a comment.