Skip to content

Instantly share code, notes, and snippets.

@spanners
Created August 28, 2013 12:06
Show Gist options
  • Save spanners/6365270 to your computer and use it in GitHub Desktop.
Save spanners/6365270 to your computer and use it in GitHub Desktop.
A way of parsing unix command output
import unittest
from mock import patch
import subprocess
import csv
class UnixCommandParser(object):
def ls_l(self, directory="."):
self.command = ['ls', '-l', directory]
self.delimiter = ' '
self.skipinitialspace = True
self.skipinitiallines = 1
self.fieldnames = ['permissions', 'links',
'owner', 'group', 'size',
'month',
'date', 'time', 'name']
return self._parse()
def ls(self, directory="."):
self.command = ['ls', directory]
self.delimiter = ' '
self.skipinitialspace = True
self.skipinitiallines = 1
self.fieldnames = ['name']
return self._parse()
def _run_command(self):
return subprocess.Popen(self.command, stdout=subprocess.PIPE).communicate()
def _get_stdout_reader(self, stdout, skip_lines=0):
return \
csv.DictReader(stdout.decode('ascii').splitlines()[self.skipinitiallines:],
delimiter=self.delimiter,
skipinitialspace=self.skipinitialspace,
fieldnames=self.fieldnames)
def _parse(self, skip_lines=0):
stdout, stderr = self._run_command()
output = [row for row in self._get_stdout_reader(stdout)]
return output
class TestUnixCommandParser(unittest.TestCase):
""" Test that Commands are parsed successfully by the parser. """
def test_ls_l(self):
""" ls -l """
fieldnames = ['permissions', 'links',
'owner', 'group', 'size',
'month',
'date', 'time', 'name']
raw_ls_l_output = \
"""total 752
-rw-rw-r-- 1 svnmirror subversion 3925 Jun 25 15:23 BUG_EXAMPLES.md
-rw-rw-r-- 1 svnmirror subversion 1210 Jul 16 08:29 code_under_test.py
-rw-rw-r-- 1 svnmirror subversion 2040 Jul 15 10:28 code_under_test.pyc"""
list_ls_l_output = [["-rw-rw-r--", "1", "svnmirror", "subversion", \
"3925", "Jun", "25", "15:23", "BUG_EXAMPLES.md"],
["-rw-rw-r--", "1", "svnmirror", "subversion", \
"1210", "Jul", "16", "08:29", "code_under_test.py"],
["-rw-rw-r--", "1", "svnmirror", "subversion", \
"2040", "Jul", "15", "10:28", "code_under_test.pyc"]]
expected_output = [dict(zip(fieldnames, line)) \
for line in list_ls_l_output]
with patch('subprocess.Popen') as mock_popen:
instance = mock_popen()
instance.communicate.return_value = [raw_ls_l_output, "foo"]
parser = UnixCommandParser()
output = parser.ls_l()
self.assertEquals(output, expected_output)
def main():
unittest.main()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment