A Command class to run shell commands.

Updated Gribouillis 4 Tallied Votes 3K Views Share

Sometimes, you just want to run a system command from python and capture its output. Currently, the standard way to do this is to call the subprocess.Popen with convenient arguments and use the communicate method. After writing such code a few times, I wrote this little Command class to ease the process. Its functionalities are limited, but in many cases, it does just what you need :)

class Command(object):
    """Run a command and capture its output string, error string and exit status"""

    def __init__(self, command):
        self.command = command 

    def run(self, shell=True):
        import subprocess as sp
        process = sp.Popen(self.command, shell = shell, stdout = sp.PIPE, stderr = sp.PIPE)
        self.pid = process.pid
        self.output, self.error = process.communicate()
        self.failed = process.returncode
        return self

    def returncode(self):
        return self.failed


>>> import random
>>> com = Command("python " + random.__file__).run()
>>> com.command
'python /usr/lib64/python2.6/random.pyc'
>>> com.failed  # This is the same as com.returncode
>>> com.error   # a string containing the command's output to sderr
>>> com.output  # a string containing the command's output to stdout
'2000 times random\n0.002 sec, avg 0.500354, stddev 0.286243, min 4.19235e-05, max 0.999824\n2000 times normalvariate\n0.005 sec, avg -0.0456954, stddev 1.01618, min -4.34149, max 3.71569\n2000 times lognormvariate\n0.006 sec, avg 1.67582, stddev 2.1577, min 0.0130835, max 27.6211\n2000 times vonmisesvariate\n0.008 sec, avg 0.000978862, stddev 1.27699, min -3.12997, max 3.13102\n2000 times gammavariate\n0.005 sec, avg 0.0117903, stddev 0.113468, min 0, max 3.18164\n2000 times gammavariate\n0.006 sec, avg 0.100394, stddev 0.303206, min 2.25924e-41, max 4.31051\n2000 times gammavariate\n0.006 sec, avg 0.156527, stddev 0.474151, min 9.58065e-32, max 6.93513\n2000 times gammavariate\n0.006 sec, avg 0.461281, stddev 0.622641, min 4.32974e-07, max 5.10383\n2000 times gammavariate\n0.006 sec, avg 0.882037, stddev 0.927279, min 0.000321367, max 8.67581\n2000 times gammavariate\n0.004 sec, avg 1.03357, stddev 1.05707, min 0.000607494, max 9.39937\n2000 times gammavariate\n0.009 sec, avg 1.98497, stddev 1.37387, min 0.0361573, max 8.97308\n2000 times gammavariate\n0.024 sec, avg 20.0889, stddev 4.46901, min 9.03523, max 37.661\n2000 times gammavariate\n0.008 sec, avg 200.137, stddev 13.8219, min 152.049, max 252.718\n2000 times gauss\n0.005 sec, avg -0.0116195, stddev 1.01896, min -3.50421, max 3.81432\n2000 times betavariate\n0.016 sec, avg 0.501708, stddev 0.185683, min 0.0439793, max 0.973224\n2000 times triangular\n0.004 sec, avg 0.445065, stddev 0.214846, min 0.0164006, max 0.969638\n'

deonis 0 Light Poster

Nice post and exactly what I want! I'm using xterm to run shell program and I absolutely need to see the output of the program. I notice a strange behaviour of the subprocess module, when ever I try to run child process it hangs my parent window until I close or kill a child process. At the same time, running above script without input or output from child process resolve that issue but now I can not get termination signal 0. Maybe I am doing something wrong ? Or maybe it's subprocess issue. Can somebody help ?

import subprocess as sp
xl=sp.Popen("xterm  -hold -e  /usr/bin/python",  shell=True, stderr=sp.PIPE, stdout=sp.PIPE)
pid = xl.pid
stdout_value, stderr_value= xl.communicate()
failed = xl.returncode
print xlp, pid, failed
~s.o.s~ 2,560 Failure as a human Team Colleague Featured Poster

Also have a look at Envoy by Kenneth. Similar approach with a few more abstractions.

Gribouillis commented: thanks for the link +13
deonis 0 Light Poster

Thanks I will take a look !!!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.