问题
The following code prints nothing, but it should print out "a" repeatedly. The forked process blocks on the os.read(0, 1). The parent process is indeed writing to the stdin_master, but stdin_slave receives nothing. Any ideas?
import os
import pty
import resource
import select
import signal
import time
stdin_master, stdin_slave = pty.openpty()
stdout_master, stdout_slave = pty.openpty()
stderr_master, stderr_slave = pty.openpty()
pid = os.fork()
# child process
if pid == 0:
os.setsid()
os.close(stdin_master)
os.close(stdout_master)
os.close(stderr_master)
os.dup2(stdin_slave, 0)
os.dup2(stdout_slave, 1)
os.dup2(stderr_slave, 2)
max_fd = resource.getrlimit(resource.RLIMIT_NOFILE)[0]
os.closerange(3, max_fd)
while True:
char = os.read(0, 1)
os.write(1, char)
os._exit(255)
# parent process
else:
os.close(stdin_slave)
os.close(stdout_slave)
os.close(stderr_slave)
try:
while True:
read, write, err = select.select([stdout_master], [stdin_master], [], 0)
for to_read in read:
print os.read(to_read, 1)
for to_write in write:
os.write(to_write, "a")
time.sleep(0.1)
finally:
os.kill(pid, signal.SIGKILL)
回答1:
I'm not sure your want to be using the pty
module here. What you seem to need is basically a pair of os.pipe's.
Here's a solution that works using pipes:
import os
import select
import signal
import time
stdin_slave, stdout_master = os.pipe()
stdin_master,stdout_slave = os.pipe()
pid = os.fork()
# child process
if pid == 0:
while True:
char = os.read(stdin_slave, 1)
os.write(stdout_slave, char)
os._exit(255)
# parent process
else:
try:
while True:
read, write, err = select.select([stdin_master], [stdout_master], [], 0)
for to_read in read:
print os.read(to_read, 1)
for to_write in write:
os.write(to_write, "a")
time.sleep(0.1)
finally:
os.kill(pid, signal.SIGKILL)
回答2:
Thomas Wouters was kind enough to furnish the answer:
PTYs can only be read from the master fd. So the child's os.read(0, 1) was not working because of this. If we change
stdin_master, stdin_slave = pty.openpty()
to
stdin_slave, stdin_master = pty.openpty()
Now the chlid will be reading from the master, and we'll be writing to the slave from the parent. This works.
来源:https://stackoverflow.com/questions/12308186/why-can-i-not-read-from-stdin-in-this-forked-process