Skip to content

Instantly share code, notes, and snippets.

@skeptycal
Created February 13, 2020 09:17
Show Gist options
  • Save skeptycal/77c36302042991de37959c8c9bc143ed to your computer and use it in GitHub Desktop.
Save skeptycal/77c36302042991de37959c8c9bc143ed to your computer and use it in GitHub Desktop.
Redirect captured shell output to a file (perhaps to process it first?)
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
# In reference to STACK OVERFLOW question #
# I wrote this to play with while I was answering a Stack Overflow question.
# I'm sure there are ways to improve it, but it was just a quick example
# for the person trying to figure out a problem.
import subprocess
import sys
import locale
from os import linesep as NL
from pathlib import Path
from sys import argv, platform
from typing import Dict, List, Sequence
# ---------------------- utility functions
def br(n: int = 1, retval: bool = False):
""" #### Prints a blank line using the OS specific line
separator from `os.linesep`.
Yes, it is just a shorter pythonic version of
`<br />`
"""
if retval:
return NL*n
print(NL*n, sep='', end='')
def j(s: Sequence, sep=', ') -> str:
""" #### Returns string of joined sequence items.
Yes, it is just a shorter version of
`', '.join(sequence)`
"""
return sep.join(s)
class ConfigVars(dict):
""" Configuration information and variable defaults """
_DEBUG_: bool = False
WIN32: bool = platform.startswith('windows')
WIDTH: int = 57
ARGS: List[str] = argv[1:]
ENCODING: str = ''
_output_filename: str = 'badfile.txt'
def __init__(self):
super().__init__(self)
try:
self.ENCODING = locale.getpreferredencoding()
except locale.Error as e:
self.ENCODING = 'utf-8' # set default on locale errors
def dir_commands(self) -> List[str]:
""" Return sample directory listing shell command. """
return ['dir', '*.*'] if self.WIN32 \
else ['ls', '-l', '.']
def output_path(self) -> str:
p = Path('C:/temp') if self.WIN32 \
else Path().home()
p /= 'temp'
p /= self._output_filename
return str(p)
def check_args(*args):
""" Respond to CLI arguments. """
pass
def test_config(*args, debug=False):
""" List debug info. """
if debug:
dunders = sorted([_ for _ in dir(c) if _.startswith('__')])
dirs = sorted([_ for _ in dir(c) if not _.startswith('__')])
_vars = [s for s in dirs if s.startswith('_')]
lowers = [s for s in dirs if s.islower()]
uppers = [s for s in dirs if s.isupper()]
br()
print('Debug Info:')
print('-'*c.WIDTH)
print(f"CONSTANTS: {uppers}")
for var in uppers:
val = eval(f"c.{var}")
print(f" {var:12.12} = {val}")
br()
print(f"properties and methods: \n\t{lowers}")
br()
# print(f"dunders: \n\t{dunders}")
# br()
print(f"{c.output_path()=}")
print('-'*c.WIDTH)
br()
def log_cmd(*args) -> int:
""" Log shell commands to a file.
Parameters:
c: a ConfigVars object with variables, data, and utilities
Returns:
int -- error code; 0 for success
One-liner:
with open('C:/temp/badfile.txt', mode='at',) as f:
f.write(subprocess.check_output(['dir','*.*']).decode())
"""
try:
retval = subprocess.check_output(c.dir_commands()).decode()
if c._DEBUG_:
print(f'function return value:\n\n{retval}')
except Exception as e:
print(f"Error processing command: {' '.join(c.dir_commands())}")
print(e)
with open(str(c.output_path()), mode='at',) as f:
try:
if c._DEBUG_:
print('Debug Info for Output File System:')
print(f" {sys.byteorder=}")
print(f" {sys.api_version=}")
print(f" {f.fileno()=}")
print(f" {f.isatty()=}")
print(f" {f.seekable()=}")
print(f" {f.writable()=}")
f.write(retval)
except Exception as e:
print(f"Error writing to file: {c.output_path()}")
print(e)
def main(*args):
'''
CLI script main entry point.
'''
check_args(c) # do more stuff with args
test_config(c, debug=c._DEBUG_)
retval = log_cmd()
if retval:
print('Errors occurred with the command logging.')
if __name__ == "__main__": # if script is loaded directly from CLI
c = ConfigVars()
c._DEBUG_ = True
main(c)
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
from subprocess import check_output
from sys import argv
if len(argv) > 1:
with open('sp.log', mode='at',) as f:
try:
f.write(check_output(argv[1:]).decode())
except Exception as e:
print(e)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment