3

I am trying to run a bash script (@command) that requires user input and I'm trying to feed that script input using the following code:

Open3.popen3(@command) do |stdin, stdout, stderr|
  stdin.write("y")
  stdout.gets
end

Here is an idea of the script:

exec sudo su -c "some command" $username

If anyone could tell me what I am doing wrong or has any suggestions on how to implement this a different way, that would be much appreciated.


Also, I can run the script like this:

@output = `#{@command}`

In this case, I can see the contents of the script output in the console I am running my app from. If there is anyway to feed input to that location that would work too.

anthv123
  • 523
  • 1
  • 8
  • 20

2 Answers2

0

Got my solution here: How to fix hanging popen3 in Ruby?

Open3.popen3(@command) do |stdin, stdout, stderr|
  stdin.puts "y\r\n"

  stdout.each_line { |line| puts line }
  stdin.close
end
Community
  • 1
  • 1
anthv123
  • 523
  • 1
  • 8
  • 20
  • 1
    If your code is expecting input on STDIN, you need to `close` STDIN after sending your input, otherwise it could hang waiting for more. Merely sending a line with line-ends is usually not enough, the stream has to be closed, just as the answers said that you referred to. – the Tin Man Jun 14 '13 at 23:01
  • 1
    Ignoring `stderr` is fatal if the subprocess tries to write much data to it. If the size of the buffer of the pipe is exceeded, the operation will suspend the suprocess. See the manual page of [pipe](http://linux.die.net/man/7/pipe). You can avoid this by using `Open3.popen2e` or `Open3.capture*`. – hagello Nov 30 '14 at 09:44
  • 1
    If your `@command` is `cat`, you need to close `stdin` _before_ reading from stdout. Otherwise `cat` will keep waiting from input and reading from `stdout` will hang. The rule of thumb is: Close `stdin` as early as possible in order to let your subprocess know that no more data will come. Even better, use the standard wrappers: `Open3.capture2*`. – hagello Nov 30 '14 at 09:49
0
out_err, status = Open3.capture2e(@command, :stdin_data => "y\r\n")
print out_err
hagello
  • 2,843
  • 2
  • 27
  • 37