In Ruby, is it possible to prevent the standard input of a spawned child process from being attached to the terminal without having to capture the STDOUT
or STDERR
of that same process?
Backticks and x-strings (`...`
, %x{...}
) don't work because they capture STDIN.
Kernel#system
doesn't work because it leaves STDIN attached to the
terminal (which intercepts signals like ^C
and prevents them from
reaching my program, which is what I'm trying to avoid).
Open3
doesn't work because its methods capture either STDOUT
or
both STDOUT
and STDERR
.
So what should I use?
If you’re on a platform that supports it, you could do this with pipe
, fork
and exec
:
# create a pipe
read_io, write_io = IO.pipe
child = fork do
# in child
# close the write end of the pipe
write_io.close
# change our stdin to be the read end of the pipe
STDIN.reopen(read_io)
# exec the desired command which will keep the stdin just set
exec 'the_child_process_command'
end
# in parent
# close read end of pipe
read_io.close
# write what we want to the pipe, it will be sent to childs stdin
write_io.write "this will go to child processes stdin"
write_io.close
Process.wait child