stdout, , -, , , .
, spawn : pty pty.fork() stdin/stdout. .
spawn, :
1: , , , ( here python)
$ python <(cat << EOF
import sys
import pty
print 'start to stdout only'
pty.spawn(sys.argv[1:])
print 'complete to stdout only'
EOF
) bash -c 'cat > out.txt'
:
start to stdout only
hello
complete to stdout only
, ( ) . out.txt :
$ cat out.txt
hello
, .
2:. , , , out python , - , :
python <(cat << EOF
import sys
import pty
import os
old_stdout = sys.stdout
sys.stdout = myfdout = os.fdopen(4,"w")
print 'start to out file only'
myfdout.flush()
pty.spawn(sys.argv[1:])
print 'complete to out file only'
sys.stdout = old_stdout
EOF
) bash -c 'cat >&4' 4>out.txt
( , ):
hello
out :
$ cat out.txt
start to out file only
hello
complete to out file only
: python pty : , python- stdout stdin. Id , pty.fork(), stdin/stdout .
stdout python . , pty , - stdin stdout . stdout () , pty.
1 - stdout - pty.spawn, pty stdout ( stdin )
2 (, 4) stdout, python (.. )
pty, pty.spawn - , stdout . - stdin.
, pty , , pty.fork() ( , , pty.spawn)
EDIT pty.fork():
import sys
import pty
import os
import select
import time
import tty
import termios
print 'start'
try:
pid, fd = pty.fork()
print 'forked'
except OSError as e:
print e
if pid == pty.CHILD:
cmd = sys.argv[1]
args = sys.argv[1:]
print cmd, args
os.execvp(cmd,args)
else:
tty.setraw(fd, termios.TCSANOW)
try:
child_file = os.fdopen(fd,'rw')
read_list = [sys.stdin, child_file]
while read_list:
ready = select.select(read_list, [], [], 0.1)[0]
if not ready and len(read_list) < 2:
break
elif not ready:
time.sleep(1)
else:
for file in ready:
try:
line = file.readline()
except IOError as e:
print "Ignoring: ", e
line = None
if not line:
read_list.remove(file)
else:
if file == sys.stdin:
os.write(fd,line)
else:
print "from child:", line
except KeyboardInterrupt:
pass
EDIT question pty.fork()
:
pty.fork():
pty.fork(), : , , , pty.fork().
- , (), - ().
pid fd -, stdin stdout: , fd, , ; fd, childs stdin. , stdout/stdin.
pid 0, fd . , stdin/stdout, , - .
, , pid. , , , - . :
if pid == pty.CHILD:
....
else
...
pty. os.execvp , pty , , pty.spawn()'. This means the child stdin/stdout are now connected to the command you wanted via a pty. IMmportantly, any input or output from the command (or the pty for that matter) will be available to the parent thread by reading from fd . And the parent can write to the command via pty by writing to fd`
, , , stdin/stdout stdin/stdout fd. , ( else). , stdin, fd. , fd (), . , , , - stdin/stdout fd. - , , .
, , :
tty.setraw(fd, termios.TCSANOW)
pty -.
, :
-
- - (.. )
-
- , stdout, stdin/stdout
- - stdin
- - ?