Skip to content

Instantly share code, notes, and snippets.

@fthiery
Created November 28, 2018 11:02
Show Gist options
  • Save fthiery/da43365ceeefff8a9e3d0dd83ec24af9 to your computer and use it in GitHub Desktop.
Save fthiery/da43365ceeefff8a9e3d0dd83ec24af9 to your computer and use it in GitHub Desktop.
Python3 example to use Gio and GLib to run subprocesses and asynchronously read stdout/stderr
#!/usr/bin/env python3
from gi.repository import Gio, GLib
import shlex
import signal
priority = GLib.PRIORITY_DEFAULT
class ProcessLauncher:
def run(self, cmd):
self.cancellable = Gio.Cancellable()
try:
flags = Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_MERGE
args = shlex.split(cmd)
self.process = p = Gio.Subprocess.new(args, flags)
p.wait_check_async(
cancellable=self.cancellable,
callback=self._on_finished
)
print('Started')
stream = p.get_stdout_pipe()
self.data_stream = Gio.DataInputStream.new(stream)
self.queue_read()
except GLib.GError as e:
print(e)
def queue_read(self):
self.data_stream.read_line_async(
io_priority=priority,
cancellable=self.cancellable,
callback=self._on_data
)
def cancel_read(self):
print('Cancelling read')
self.cancellable.cancel()
def _on_finished(self, proc, results):
print('Process finished')
try:
proc.wait_check_finish(results)
except Exception as e:
print(e)
self.cancel_read()
def _on_data(self, source, result):
try:
line, length = source.read_line_finish_utf8(result)
if line:
print(line)
except GLib.GError as e:
print(e)
return
self.queue_read()
def stop(self):
print('Stop')
self.process.send_signal(signal.SIGTERM)
def kill(self):
print('Kill')
self.cancel_read()
self.process.send_signal(signal.SIGKILL)
if __name__ == '__main__':
p = ProcessLauncher()
m = GLib.MainLoop()
GLib.idle_add(p.run, "/usr/bin/journalctl -f")
GLib.timeout_add_seconds(priority=priority, interval=5, function=p.stop)
m.run()
@fthiery
Copy link
Author

fthiery commented Feb 25, 2020

TBH i just found it somewhere and stored it exactly for the same reason. Thanks for the investigation !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment