Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there anything like Python's pty.fork for Ruby?

I'm trying to port some Python code like the following to Ruby:

import pty

pid, fd = pty.fork
if pid == 0:
  # figure out what to launch
  cmd = get_command_based_on_user_input()

  # now replace the forked process with the command
  os.exec(cmd)
else:
  # read and write to fd like a terminal

Since I need to read and write to the subprocess like a terminal, I understand that I should use Ruby's PTY module in lieu of Kernel.fork. But it does not seem to have an equivalent fork method; I must pass a command as a string. This is the closest I can get to Python's functionality:

require 'pty'

# The Ruby executable, ready to execute some codes
RUBY = %Q|/proc/#{Process.id}/exe -e "%s"|

# A small Ruby program which will eventually replace itself with another program. Very meta.
cmd = "cmd=get_command_based_on_user_input(); exec(cmd)"

r, w, pid = PTY.spawn(RUBY % cmd)
# Read and write from r and w

Obviously some of that is Linux-specific, and that's fine. And obviously some is pseudo-code, but it's the only approach I can find, and I'm only 80% sure that it will work anyway. Surely Ruby has something cleaner?

The important thing is that "get_command_based_on_user_input()" not block the parent process, which is why I stuck it in the child process.

like image 408
bioneuralnet Avatar asked Nov 13 '22 17:11

bioneuralnet


1 Answers

You're probably looking for http://ruby-doc.org/stdlib-1.9.2/libdoc/pty/rdoc/PTY.html, http://www.ruby-doc.org/core-1.9.3/Process.html#method-c-fork and Create a daemon with double-fork in Ruby.

I'd open a PTY with master process, fork and reattach child to said PTY with STDIN.reopen.

like image 107
Slotos Avatar answered Dec 22 '22 08:12

Slotos