함수 glib.spawn_async은 stdout
, stderr
및 처리 완료시 이벤트에서 호출되는 세 가지 콜백을 후크 할 수 있습니다.팝업으로 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()
을 사용하고, 명령의 끝에서 이전에 읽지 않은 모든 행을 읽는 것을 끝내야합니다.
하위 프로세스 및 스레드와
import asyncio
class Handler(asyncio.SubprocessProtocol):
def pipe_data_received(self, fd, data):
# fd == 1 for stdout, and 2 for stderr
print("Data from /bin/ls on fd %d: %s" % (fd, data.decode()))
def pipe_connection_lost(self, fd, exc):
print("Connection lost to /bin/ls")
def process_exited(self):
print("/bin/ls is finished.")
loop = asyncio.get_event_loop()
coro = loop.subprocess_exec(Handler, "/bin/ls", "/")
loop.run_until_complete(coro)
loop.close()
, 그것뿐만 아니라 간단합니다
시간을내어이 답변을 작성해 주셔서 감사합니다. – Sardathrion
위의 코드는'readlines()'가 블로킹하는 것처럼'stdout'과'stderr'의 라인을 버퍼링합니다. 업데이트를 원한다면'read()'를 사용하고 리더 쓰레드가 끝나면 버퍼를 비운다. – Sardathrion