Created
February 13, 2020 09:17
-
-
Save skeptycal/77c36302042991de37959c8c9bc143ed to your computer and use it in GitHub Desktop.
Redirect captured shell output to a file (perhaps to process it first?)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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