関数glib.spawn_asyncは、stdout
、stderr
、および処理完了時にイベントで呼び出される3つのコールバックをフックできます。Popupでglib.spawn_asyncを模倣します。
subprocessと同じ機能を、スレッドまたはasyncioでどのように模倣できますか?
私はスレッド/ asynioではなく機能性に興味がありますが、両方を含む回答では賞金が得られます。ここで
は、私が何をしたいのかを示しおもちゃのプログラムです:
import glib
import logging
import os
import gtk
class MySpawn(object):
def __init__(self):
self._logger = logging.getLogger(self.__class__.__name__)
def execute(self, cmd, on_done, on_stdout, on_stderr):
self.pid, self.idin, self.idout, self.iderr = \
glib.spawn_async(cmd,
flags=glib.SPAWN_DO_NOT_REAP_CHILD,
standard_output=True,
standard_error=True)
fout = os.fdopen(self.idout, "r")
ferr = os.fdopen(self.iderr, "r")
glib.child_watch_add(self.pid, on_done)
glib.io_add_watch(fout, glib.IO_IN, on_stdout)
glib.io_add_watch(ferr, glib.IO_IN, on_stderr)
return self.pid
if __name__ == '__main__':
logging.basicConfig(format='%(thread)d %(levelname)s: %(message)s',
level=logging.DEBUG)
cmd = '/usr/bin/git ls-remote https://github.com/DiffSK/configobj'.split()
def on_done(pid, retval, *args):
logging.info("That's all folks!…")
def on_stdout(fobj, cond):
"""This blocks which is fine for this toy example…"""
for line in fobj.readlines():
logging.info(line.strip())
return True
def on_stderr(fobj, cond):
"""This blocks which is fine for this toy example…"""
for line in fobj.readlines():
logging.error(line.strip())
return True
runner = MySpawn()
runner.execute(cmd, on_done, on_stdout, on_stderr)
try:
gtk.main()
except KeyboardInterrupt:
print('')
私はreadlines()
以来、すべての出力をバッファリングし、一度にそれを送信します上記、ブロックしていることを追加する必要があります。これが何を望んでいないのであれば、readline()
を使用し、コマンドの最後にあなたが以前に読んでいなかったすべての行を読み終えるようにしなければなりません。
この回答を書いていただきありがとうございます。 – Sardathrion
上記はreadline()がブロックしているので 'stdout'と' stderr'の行をバッファします。更新が必要な場合は 'read()'を使用しますが、リーダースレッドが終了したらバッファを空にしてください。 – Sardathrion