Skip to content

Instantly share code, notes, and snippets.

@simonLeary42
Last active April 16, 2023 20:19
Show Gist options
  • Select an option

  • Save simonLeary42/6a3123cf6657eeabe5e2bf6bf118330e to your computer and use it in GitHub Desktop.

Select an option

Save simonLeary42/6a3123cf6657eeabe5e2bf6bf118330e to your computer and use it in GitHub Desktop.
import re
def indent(string: str, indenter=" ", num_indents=1) -> str:
for i in range(num_indents):
string = indenter + string # first line
string = string.replace('\n', '\n'+indenter) # all other lines
return string
def remove_empty_lines(string: str) -> str:
return re.sub(r"\n{2,}", '\n', string)
class ShellRunner:
"""
spawn this with a shell command, then you have access to stdout, stderr, exit code,
along with a boolean of whether or not the command was a success (exit code 0)
and if you use str(your_shell_runner), you get a formatted report of all the above
"""
def __init__(self, command, timeout_s):
try:
process = subprocess.run(
command,
capture_output=True,
shell=True,
timeout=timeout_s
)
# process.std* returns a bytes object, convert to string
self.shell_output = remove_empty_lines(str(process.stdout, 'UTF-8'))
self.shell_error = remove_empty_lines(str(process.stderr, 'UTF-8'))
self.exit_code = process.returncode
except subprocess.TimeoutExpired as timeout_err:
try:
self.shell_output = remove_empty_lines(str(timeout_err.stdout, 'UTF-8'))
except TypeError:
self.shell_output = ''
try:
self.shell_error = remove_empty_lines(str(timeout_err.stderr, 'UTF-8'))
except TypeError:
self.shell_error = f'timeout after {timeout_s} seconds!'
self.exit_code = 1
self.success = self.exit_code == 0
self.command_report = '\n'.join([
"command:",
indent(command),
f"exit code: {self.exit_code}",
'',
"stdout:",
indent(self.shell_output),
'',
"stderr:",
indent(self.shell_error),
])
def __str__(self):
return self.command_report
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment