diff --git a/.gitattributes b/.gitattributes
index 8c45cec5081cc6da5bbb496a1cf6f6c22828a99d..5f5cb05926ee9fe7103fd992dbe964119dbb83cb 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -2683,6 +2683,7 @@ LCS/PyCommon/__init__.py -text
 LCS/PyCommon/datetimeutils.py -text
 LCS/PyCommon/factory.py -text
 LCS/PyCommon/postgres.py -text
+LCS/PyCommon/subprocess.py -text
 LCS/PyCommon/test/python-coverage.sh eol=lf
 LCS/PyCommon/test/t_dbcredentials.run eol=lf
 LCS/PyCommon/test/t_dbcredentials.sh eol=lf
diff --git a/LCS/PyCommon/CMakeLists.txt b/LCS/PyCommon/CMakeLists.txt
index 7ab73b50fc58d930bd66d0c962c9d04298fb5250..a919cec71b6106e2dff3605edb7ec52380b7f975 100644
--- a/LCS/PyCommon/CMakeLists.txt
+++ b/LCS/PyCommon/CMakeLists.txt
@@ -12,7 +12,8 @@ set(_py_files
   methodtrigger.py
   util.py
   postgres.py
-  datetimeutils.py)
+  datetimeutils.py
+  subprocess.py)
 
 python_install(${_py_files} DESTINATION lofar/common)
 
diff --git a/LCS/PyCommon/subprocess.py b/LCS/PyCommon/subprocess.py
new file mode 100644
index 0000000000000000000000000000000000000000..cec18eeb8311581107b883570d4682251449ee39
--- /dev/null
+++ b/LCS/PyCommon/subprocess.py
@@ -0,0 +1,43 @@
+from threading  import Thread
+try:
+    from Queue import Queue, Empty
+except ImportError:
+    from queue import Queue, Empty  # python 3.x
+
+class PipeReader:
+    '''
+    helper class to do non-blocking readline calls to a subprocess stdput or stderr pipe.
+    '''
+    def __init__(self, pipe):
+        self.__line_buffer = ''
+        self.__queue = Queue()
+        self.__thread = Thread(target=PipeReader.enqueue_output, args=(pipe, self.__queue))
+        self.__thread.daemon = True # thread dies with the program
+        self.__thread.start()
+
+    @staticmethod
+    def enqueue_output(pipe, queue):
+        try:
+            for line in iter(pipe.readline, b''):
+                queue.put(line)
+        except Exception as e:
+            logger.error(e)
+
+    def readline(self, timeout=None):
+        start = datetime.now()
+        while timeout==None or datetime.now() - start <= timedelta(seconds=timeout):
+            try:
+                result = self.__queue.get(True, timeout)
+                if result:
+                    self.__line_buffer += result
+            except Empty:
+                pass
+
+        endline_idx = self.__line_buffer.find('\n')
+
+        if endline_idx > -1:
+            line = self.__line_buffer[:endline_idx]
+            self.__line_buffer = self.__line_buffer[endline_idx+1:]
+            return line
+        return ''
+