I think I finally got a minimal example for pty.fork in Python - and since it was very difficult for me to find a similar example, I am posting it here as an illustration of @joni's answer. It is based mainly on:
Particularly unpleasant bits are the documentation, which still refers to master_open() , which is deprecated; and the fact that pty.fork will not spawn a child process if the file descriptor (returned by the fork method) is not read by the parent process! (note that there is os.fork such requirement in os.fork ). It also seems that os.fork bit more portable (read a few comments, noting that pty.fork does not work on some platforms).
In any case, here is the first script ( pyecho.py ), which acts as an executable file (it just reads the lines from standard input and writes them back in upper case):
#!/usr/bin/env python # pyecho.py import sys; print "pyecho starting..." while True: print sys.stdin.readline().upper()
... and now, here is the actual script (this would require pyecho.py to be in the same directory):
#!/usr/bin/env python import sys import os import time import pty def my_pty_fork(): # fork this script try: ( child_pid, fd ) = pty.fork() # OK #~ child_pid, fd = os.forkpty() # OK except OSError as e: print str(e) #~ print "%d - %d" % (fd, child_pid) # NOTE - unlike OS fork; in pty fork we MUST use the fd variable # somewhere (ie in parent process; it does not exist for child) # ... actually, we must READ from fd in parent process... # if we don't - child process will never be spawned! if child_pid == 0: print "In Child Process: PID# %s" % os.getpid() # note: fd for child is invalid (-1) for pty fork! #~ print "%d - %d" % (fd, child_pid) # the os.exec replaces the child process sys.stdout.flush() try: #Note: "the first of these arguments is passed to the new program as its own name" # so:: "python": actual executable; "ThePythonProgram": name of executable in process list (`ps axf`); "pyecho.py": first argument to executable.. os.execlp("python","ThePythonProgram","pyecho.py") except: print "Cannot spawn execlp..." else: print "In Parent Process: PID# %s" % os.getpid() # MUST read from fd; else no spawn of child! print os.read(fd, 100) # in fact, this line prints out the "In Child Process..." sentence above! os.write(fd,"message one\n") print os.read(fd, 100) # message one time.sleep(2) os.write(fd,"message two\n") print os.read(fd, 10000) # pyecho starting...\n MESSAGE ONE time.sleep(2) print os.read(fd, 10000) # message two \n MESSAGE TWO # uncomment to lock (can exit with Ctrl-C) #~ while True: #~ print os.read(fd, 10000) if __name__ == "__main__": my_pty_fork()
Ok, hope this helps someone
Hooray!
sdaau
source share