python pty.fork - 它是如何工作的

web*_*org 8 python pty

http://docs.python.org/library/pty.html说 -

pty.fork()福克.将孩子的控制终端连接到伪终端.返回值为(pid,fd).请注意,子项获取pid 0,并且fd无效.父级的返回值是子级的pid,fd是连接到子级控制终端(以及子级标准输入和输出)的文件描述符.

这是什么意思?每个进程都有3个fd(stdin,stdout,stderr).这会影响这些fds吗?子进程是否会有这些fds?我很困惑.--完全.

sda*_*aau 13

我想我终于pty.fork在Python中得到了一个最小的例子- 因为我发现找到一个类似的例子非常困难,我在这里发布它是为了解释@ joni的答案.它基本上基于:

特别令人讨厌的一点是找到文件,仍然指的master_open()是过时的; 而事实pty.fork不会产生一个子进程,除非该文件描述符(由叉方法返回)从父进程读取!(请注意,os.fork没有这样的要求)此外,它似乎os.fork更容易移植(阅读一些注释,pty.fork在某些平台上不起作用).

无论如何,这里首先是一个pyecho.py充当可执行文件的脚本()(它只是从标准输入中读取行,然后以大写形式写回):

#!/usr/bin/env python
# pyecho.py

import sys;

print "pyecho starting..."

while True:
  print sys.stdin.readline().upper()
Run Code Online (Sandbox Code Playgroud)

...然后,这是实际的脚本(它将要求pyecho.py位于同一目录中):

#!/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 (i.e. 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()
Run Code Online (Sandbox Code Playgroud)

嗯,希望这有助于某人,
干杯!


Pet*_*tri 5

使用 pty.fork() 的要点是返回的伪终端 (pty) 文件描述符可用于以不同的方式与生成的进程进行通信,即。通过直接写入和读取其(伪)终端 - 而不是 stdin/out/err。

还有更多关于 pty 和 tty 的信息(来自 StackOverflow),以及一个使用 pty.fork() 的简单示例的链接


jon*_*oni 3

“而 fd 是连接到 child\xe2\x80\x99s 控制终端的文件描述符” --> 子进程不会看到任何差异,它将能够正常访问 stdin/out (我不知道 stderr)。唯一的区别是,“管道”的另一端不是用户正在读取/键入的终端,而是可以通过返回的 fd 访问的父进程。

\n