user47322
user47322

Reputation:

How do I open STDIN of process in Ruby?

I have a set of tasks that I need to run from a Ruby script, however one particular task always waits for EOF on STDIN before quitting.

Obviously this causes the script to hang while waiting for the child process to end.

I have the process ID of the child process, but not a pipe or any kind of handle to it. How could I open a handle to the STDIN of a process to send EOF to it?

Upvotes: 1

Views: 1901

Answers (1)

Aidan Cully
Aidan Cully

Reputation: 5507

EDIT: Given that you aren't starting the script, a solution that occurs to me is to put $stdin under your control while using your gem. I suggest something like:

old_stdin = $stdin.dup
# note that old_stdin.fileno is non-0.
# create a file handle you can use to signal EOF
new_stdin = File::open('/dev/null', 'r')
# and make $stdin use it, instead.
$stdin.reopen(new_stdin)
new_stdin.close
# note that $stdin.fileno is still 0, though now it's using /dev/null for input.
# replace with the call that runs the external program
system('/bin/cat')
# "cat" will now exit.  restore the old state.
$stdin.reopen(old_stdin)
old_stdin.close

If your ruby script is creating the tasks, it can use IO::popen. For example, cat, when run with no arguments, will wait for EOF on stdin before it exits, but you can run the following:

f = IO::popen('cat', 'w')
f.puts('hello')
# signals EOF to "cat"
f.close

Upvotes: 7

Related Questions