Skip to content

Instantly share code, notes, and snippets.

@ksvbka
Last active January 5, 2019 02:42
Show Gist options
  • Save ksvbka/2bc8ade594eb9604d1f323083779c224 to your computer and use it in GitHub Desktop.
Save ksvbka/2bc8ade594eb9604d1f323083779c224 to your computer and use it in GitHub Desktop.
redirect linux cmd to logfile or print to screen
import os
import uuid
import threading
import logging
import subprocess
class LogPipe(threading.Thread):
def __init__(self, logfile=None, level=logging.INFO):
"""Setup the object with a logger and a loglevel and start the thread
Alway print to logfile and only print to screen if level is DEBUG
"""
threading.Thread.__init__(self)
self.daemon = False
self.level = level
self.fd_read, self.fd_write = os.pipe()
self.pipe_reader = os.fdopen(self.fd_read)
# Config log file
# FIXME: workaround to bypass error alway print to screen after call run with verbose
self.logger = logging.getLogger(str(uuid.uuid1()))
self.logger.setLevel(logging.DEBUG)
console_handler = logging.StreamHandler()
console_handler.setLevel(level)
self.logger.addHandler(console_handler)
if logfile:
open(logfile, 'w').close() # clear file
file_hander = logging.FileHandler(logfile)
file_hander.setLevel(logging.DEBUG) # Alway print to file
self.logger.addHandler(file_hander)
self.start()
def fileno(self):
return self.fd_write
def run(self):
for line in iter(self.pipe_reader.readline, ''):
self.logger.debug(line.strip('\n'))
self.pipe_reader.close()
def close(self):
os.close(self.fd_write)
def run(cmd, logfile=None, verbose=False):
""" Run linux command
"""
level = logging.DEBUG if verbose else logging.ERROR
logpipe = LogPipe(logfile, level)
stdout = stderr = logpipe
ret = subprocess.call(cmd, shell=True, stdout=stdout, stderr=stderr)
logpipe.close()
return ret == 0
if __name__ == '__main__':
run('ls', 'test', verbose=True)
run('ls', 'test', verbose=False)
run('ls -la', 'test', verbose=True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment