Skip to content

Added print and wait #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion bash/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import sys
import sys, time
from subprocess import PIPE, Popen
SUBPROCESS_HAS_TIMEOUT = True
if sys.version_info < (3, 0):
Expand Down Expand Up @@ -39,6 +39,7 @@ def sync(self, timeout=None):
self.code = self.p.returncode
return self


def __repr__(self):
return self.value()

Expand All @@ -58,3 +59,34 @@ def value(self):
if self.stdout:
return self.stdout.strip().decode(encoding='UTF-8')
return ''

def print_and_wait(self):
"""
Continuously prints stdout and stderr of the subprocess to stdout in realtime
Returns the exit code of the subprocess once the process finishes running.
Note that if you do the following you will not see the stdout and stderr from the
subprocess until after the process completes,
process = bash('<bash commadn spawning a process>')
process.print_and_wait()
The process will finish synchronously when bash is called before print_and_wait gets called.
To see the output in realtime do the following,
process = bash('<bash commadn spawning a process>', sync=False)
process.print_and_wait()
"""
while True:
out_line = self.p.stdout.readline().decode()
err_line = self.p.stderr.readline().decode()
if len(out_line) > 0:
print(out_line)
elif len(err_line) > 0:
print(err_line)
elif self.p.poll() is None:
time.sleep(.05)
else:
break

exit_code = self.p.poll()
print(f'exit code {exit_code} from subprocess')
return exit_code


16 changes: 16 additions & 0 deletions tests.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from datetime import datetime
import unittest
import io, sys

try:
from subprocess import TimeoutExpired
Expand Down Expand Up @@ -66,3 +67,18 @@ def test_sync_false_does_not_wait(self):
self.assertTrue((t2-t1).total_seconds() < 0.5)
b.sync()
self.assertEqual(b.stdout, b'1\n')

def test_print_and_wait(self):
b = bash('echo hey', sync=False)
# with help from https://stackoverflow.com/a/35779140/3781537
old_stdout = sys.stdout
sys.stdout = io.StringIO()
b.print_and_wait()
what_was_printed = sys.stdout.getvalue()
self.assertTrue('hey' in what_was_printed)

sys.stdout = io.StringIO()
b = bash('./missing_command', sync=False)
b.print_and_wait()
self.assertTrue('No such file or directory' in sys.stdout.getvalue())
sys.stdout = old_stdout