3

在使用 PTY 主/从对控制进程时,我想向相关进程表明标准输入已关闭并且我没有更多内容要发送,但我仍想接收来自该进程的输出。

问题是我只有一个文件描述符(PTY“主”),它处理来自子进程的输入和输出到子进程。所以关闭描述符会关闭两者。

python中的示例:

import subprocess, pty, os
master,slave = pty.openpty()
proc = subprocess.Popen(["/bin/cat"], stdin=slave, stdout=slave)
os.close(slave)  # now belongs to child process
os.write(master,"foo")
magic_close_fn(master)  # <--- THIS is what I want
while True:
    out = os.read(master,4096)
    if out: 
        print out
    else: 
        break
proc.wait()
4

3 回答 3

0

您需要获得单独的读写文件描述符。简单的方法是使用管道和 PTY。所以现在你的代码看起来像这样:

import subprocess, pty, os
master, slave = pty.openpty()
child_stdin, parent_stdin = os.pipe()
proc = subprocess.Popen(["/bin/cat"], stdin=child_stdin, stdout=slave)
os.close(child_stdin)  # now belongs to child process
os.close(slave)
os.write(parent_stdin,"foo") #Write to the write end (our end) of the child's stdin
#Here's the "magic" close function
os.close(parent_stdin)
while True:
    out = os.read(master,4096)
    if out: 
        print out
    else: 
        break
proc.wait()
于 2013-08-17T17:04:34.970 回答
0

我今天必须这样做,最终来到这里,很遗憾没有答案。我使用一对 pty 而不是单个 pty 实现了这一点。

stdin_master, stdin_slave = os.openpty()
stdout_master, stdout_slave = os.openpty()
def child_setup():
    os.close(stdin_master) # only the parent needs this
    os.close(stdout_master) # only the parent needs this

with subprocess.Popen(cmd,
        start_new_session=True,
        stderr=subprocess.PIPE,
        stdin=stdin_slave,
        stdout=stdout_slave,
        preexec_fn=child_setup) as proc:
    os.close(stdin_slave) # only the child needs this
    os.close(stdout_slave) # only the child needs this
    stdin_pty = io.FileIO(stdin_master, "w")
    stdout_pty = io.FileIO(stdout_master, "r")

    stdin_pty.write(b"here is your input\r")
    stdin_pty.close() # no more input (EOF)
    output = b""
    while True:
        try:
            output += stdout_pty.read(1)
        except OSError:
            # EOF
            break
    stdout_pty.close()
于 2022-01-20T04:47:13.473 回答
-1

我认为你想要的是发送 CTRL-D(EOT - 传输结束)字符,不是吗?这将关闭某些应用程序中的输入,但其他应用程序将退出。

perl -e 'print qq,\cD,'

或纯粹的外壳:

echo -e '\x04' | nc localhost 8080

两者都只是例子。顺便说一句,CTRL-D 字符是\x04六进制的。

于 2013-08-21T19:49:40.780 回答