Running external processes/programs with Python subprocess

Note: It is good to know when the external process runs and for how long, which is included in the code snippet below. For the “when” part, it would have been nice to know the time zone as well. But due to the limitation mentioned here, it is not as easy as it sounds with the datetime module.

It seems the time module in Python has better handling of time zone, but it ends at year 2038, which is a slight concern of mine, so I decided against it. The datetime module’s upper limit is year 9999. That is pretty far into the future, if we humans haven’t managed to extinct ourselves by then.

Speaking of the Linux/Unix epoch time, I wonder if we would encounter year 2038 issue, like the much talked about Y2K back in the day 🙂

import shlex, subprocess, sys
from datetime import datetime

def runCmd(cmd):
    proc = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)

    out, err = proc.communicate()
    ret = proc.returncode
    return (ret, out, err)

startTime = datetime.now()

# "df -h" is a *nix command. To test on Windows, replace it with "notepad" or something like that.
returnCode, stdOut, stdErr = runCmd('df -h')

endTime = datetime.now()

print "The command started at " + str(startTime) + " and ran for " + str((endTime - startTime)) + "\n"

print stdOut
if returnCode:
	print >> sys.stderr, "There was an error (%d): \n" % returnCode
	print >> sys.stderr, stdErr

Update:

When I first posted this, I wrote that to test it on Windows, you can try the “dir” command. Actually, if you do, you will encounter the error below:

C:\Users\haidong\Documents\work\python>tt.py
Traceback (most recent call last):
  File "C:\Users\haidong\Documents\work\python\tt.py", line 14, in <module>
    returnCode, stdOut, stdErr = runCmd('df -h')
  File "C:\Users\haidong\Documents\work\python\tt.py", line 5, in runCmd
    proc = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
  File "C:\Python27\lib\subprocess.py", line 672, in __init__
    errread, errwrite)
  File "C:\Python27\lib\subprocess.py", line 882, in _execute_child
    startupinfo)
WindowsError: [Error 2] The system cannot find the file specified

The reason is that dir is a DOS command that needs to be run on top of the command line process. If you replace “dir” with some other independent executibles, it should work. I’ve tried both “notepad” and “sqlcmd”, and both worked for me fine. “sqlcmd” is really the one I am after.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.