我使用以下调用来生成一个进程,取回其 stdin、stdout 和 stderr 的文件描述符,并观察其 stdout 上的输出:
[widget.pid,widget.stdin,widget.stdout,widget.stderr] = \
gobject.spawn_async(['/bin/sed','s/hi/by/g'],
standard_input=True,
standard_output=True,
standard_error=True
)
gobject.io_add_watch(widget.stdout,
gobject.IO_IN,
getdata)
然后我向widget.stdin 写入行,期望触发回调函数getdata。
我发现只有在到 widget.stdin 的管道被填满后才会调用我的 getdata 回调,而不是在我发送第一个换行符后立即调用。完整的测试程序及其输出在这里。在管道填满或关闭管道之前,我没有收到任何对 getdata 的回调,然后我终于得到了 sed 返回的数据:
#!/usr/bin/env python
# example base.py
import pygtk
pygtk.require('2.0')
import gtk
import gobject
import os
import time
import fcntl
F_SETPIPE_SZ = 1031 # Linux 2.6.35+
F_GETPIPE_SZ = 1032 # Linux 2.6.35+
def data_can_be_sent(source,cb_condition):
msg = "hi there how are you\n"
try:
print "Source, cond, send", source, cb_condition, msg
#print "Also sending padding x's and a newline to make 512 bytes."
os.write(source, msg)
os.write(source,"\n")
os.write(source,"-"*(510-len(msg)))
os.write(source,"\n")
time.sleep(0.1)
except Exception as e:
print e
print "Could not print in data_can_be_sent"
return True
def getdata(source,cb_condition):
try:
p = os.read(source,4096)
print "Source, cond, get", Base.pipesize, source, cb_condition, "[", p, "]"
except:
print "Could not print in getdata."
return True
class Base:
pipesize = 0
def hello(self, widget, data=None):
print "Hello"
print gobject
try:
print "fstat",os.fstat(widget.stdin)
print "fsync"
os.fsync(widget.stdin)
except AttributeError as e:
print "Attribute Error",e
print "Spawning sed process"
[widget.pid,widget.stdin,widget.stdout,widget.stderr] = \
gobject.spawn_async(['/bin/sed','s/hi/by/g'],
standard_input=True,
standard_output=True,
standard_error=True
)
print widget.pid,widget.stdin,widget.stdout,widget.stderr
print "Pipe size",fcntl.fcntl(widget.stdin,F_GETPIPE_SZ)
print "SET Pipe size",fcntl.fcntl(widget.stdin,F_SETPIPE_SZ,10)
Base.pipesize = fcntl.fcntl(widget.stdin,F_GETPIPE_SZ)
print "Pipe size",fcntl.fcntl(widget.stdin,F_GETPIPE_SZ)
gobject.io_add_watch(widget.stdin,
gobject.IO_OUT,
data_can_be_sent)
gobject.io_add_watch(widget.stdout,
gobject.IO_IN | gobject.IO_PRI,
getdata)
os.write(widget.stdin, "aaaaaaaaaaaaaaa\n"*64)
os.write(widget.stdin, "bbbbbbbbbbbbbbb\n"*64)
os.write(widget.stdin, "ccccccccccccccc\n"*64)
os.write(widget.stdin, "ddddddddddddddd\n"*64)
except OSError as e:
print "NONATTRIB",e.errno
print "NONATTRIB",e.strerror
def delete_event(self, width, event, data=None):
print "delete event, returning False so window is destroyed"
return False
def destroy(self, widget, data=None):
print "destroy received"
gtk.main_quit()
def __init__(self):
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.connect("delete_event", self.delete_event)
# Here we connect the "destroy" event to a signal handler.
# This event occurs when we call gtk_widget_destroy() on the window,
# or if we return FALSE in the "delete_event" callback.
self.window.connect("destroy", self.destroy)
self.button = gtk.Button("Hello World")
self.button.connect("clicked", self.hello, None)
self.window.add(self.button)
self.button.show()
self.window.show()
def main(self):
gtk.main()
print __name__
if __name__ == "__main__":
base = Base()
base.main()
输出如下所示:
$ python pytest.py
__main__
Hello
<module 'gobject' from '/usr/lib/python2.7/dist-packages/gobject/__init__.pyc'>
fstat Attribute Error 'gtk.Button' object has no attribute 'stdin'
Spawning sed process
29594 16 17 19
Pipe size 65536
SET Pipe size 4096
Pipe size 4096
Source, cond, send 16 4 hi there how are you
Source, cond, send 16 4 hi there how are you
Source, cond, get 4096 17 1 [ aaaaaaaaaaaaaaa
(more a's, b's, c's, and d's)...
ddddddddddddddd
]
Source, cond, send 16 4 hi there how are you
Source, cond, send 16 4 hi there how are you
Source, cond, send 16 4 hi there how are you
Source, cond, send 16 4 hi there how are you
Source, cond, send 16 4 hi there how are you
Source, cond, send 16 4 hi there how are you
Source, cond, send 16 4 hi there how are you
Source, cond, send 16 4 hi there how are you
Source, cond, get 4096 17 1 [ by there how are you
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
by there how are you
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
by there how are you
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
by there how are you
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
by there how are you
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
by there how are you
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
by there how are you
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
by there how are you
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
]
Source, cond, send 16 4 hi there how are you
Source, cond, send 16 4 hi there how are you
Source, cond, send 16 4 hi there how are you
Source, cond, send 16 4 hi there how are you
Source, cond, send 16 4 hi there how are you
Source, cond, send 16 4 hi there how are you
Source, cond, send 16 4 hi there how are you
delete event, returning False so window is destroyed
destroy received
Source, cond, send 16 4 hi there how are you
Source, cond, get 4096 17 1 [ by there how are you
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
by there how are you
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
by there how are you
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
by there how are you
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
by there how are you
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
by there how are you
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
by there how are you
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
by there how are you
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
]
更新:为了回应下面 drahnr 的评论,我在 C 中使用 gtk 进行了尝试,并调用了
ret = g_spawn_async_with_pipes(".", /* working directory */
spawn_argv, /* gchar **argv,*/
NULL, /* gchar **envp,*/
0L, /* GSpawnFlags flags,*/
NULL, /* GSpawnChildSetupFunc child_setup,*/
NULL, /* gpointer user_data,*/
&pid, /*GPid *child_pid,*/
&spawn_stdin, /* gint *standard_input,*/
&spawn_stdout, /* gint *standard_output, */
&spawn_stderr, /* gint *standard_error, */
NULL /*GError **error*/
);
并得到相同的结果;直到至少 4096 个字节被发送到 sed 之后,sed 才会返回,即使每十个字符有一个换行符。