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
- - ?