From bce777d517cdedaf68e2547a7cf7424a6579f3f5 Mon Sep 17 00:00:00 2001 From: GonzaMartinez Date: Wed, 7 Jan 2015 00:16:35 -0300 Subject: [PATCH] add multi chained and make work pipe stdin between process --- README.rst | 7 +++---- procs/chain.py | 22 +++++++++------------- procs/process.py | 6 +++--- tests/test_chain.py | 9 +++++++++ 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/README.rst b/README.rst index 3ff450b..433f153 100644 --- a/README.rst +++ b/README.rst @@ -34,12 +34,11 @@ Advanced Usage:: >>> ls = procs.Process('ls /usr/bin') >>> grep = procs.Process('grep python') - >>> chain = ls | grep + >>> wc = procs.Process('wc -l') + >>> chain = ls | grep | wc >>> chain.run() >>> print(chain.stdout) - python - python3 - python3.4 + 19 >>> from procs import ProcessHandler diff --git a/procs/chain.py b/procs/chain.py index 55bc772..d7f0469 100644 --- a/procs/chain.py +++ b/procs/chain.py @@ -1,5 +1,4 @@ from __future__ import print_function -import os class Chain(object): @@ -7,26 +6,23 @@ class Chain(object): def __init__(self, processes): self.processes = processes - def run(self): - for proc, next_proc in zip(self.processes, self.processes[1:]): - read, write = os.pipe() - proc.set_stdout(write) - next_proc.set_stdin(read) - for proc in self.processes: + for i, proc in enumerate(self.processes, start=1): + if i > 1: + proc.set_stdin(self.processes[i-2].subprocess.stdout) proc.start() - for proc in self.processes: - proc.wait() - if proc._stdout is not None: - os.close(proc._stdout) - + if i != len(self.processes): + proc.wait(unread=True) + else: + proc.wait() @property def returncode(self): return self.processes[-1].returncode - @property def stdout(self): return self.processes[-1].stdout + def __or__(self, other): + return Chain(self.processes + [other]) diff --git a/procs/process.py b/procs/process.py index 569ba36..fbb9d57 100644 --- a/procs/process.py +++ b/procs/process.py @@ -47,12 +47,12 @@ class Process(object): args=self.command, shell=True, stdin=self._stdin if self._stdin else subprocess.PIPE, - stdout=self._stdout if self._stdout else subprocess.PIPE, + stdout=subprocess.PIPE, ) - def wait(self): + def wait(self, unread=False): self._returncode = self._subprocess.wait() - if self._subprocess.stdout is not None: + if self._subprocess.stdout is not None and not unread: self._stdout_text = self._subprocess.stdout.read().decode() diff --git a/tests/test_chain.py b/tests/test_chain.py index 2c2cf3e..efdb196 100644 --- a/tests/test_chain.py +++ b/tests/test_chain.py @@ -16,3 +16,12 @@ def test_chained_procs(): assert chain.returncode == 0 assert chain.stdout.strip() == 'file2' +def test_multi_chained_procs(): + ls = Process('ls {test_dir}'.format(test_dir=TEST_DIR)) + grep = Process('grep 2') + wc = Process('wc -c') + chain = ls | grep | wc + chain.run() + assert chain.returncode == 0 + assert chain.stdout.strip() == '6' +