Python Running System Command
So there are a few ways to run system command using python, but I tend to find the below approach the easiest to use and has error handling.
First off I would create a function rather than running the commands over and over:
import subprocess
def run(command):
'''takes a string command and hands back a subprocess object'''
process = subprocess.Popen(command.split(), shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
process.wait()
return process
The function itself is pretty small and makes use of the subprocess library .
Popen takes a list which is each part of your command, for example the command ls -lt file would be written as:
['ls', '-lt', 'file']
This however is avoided by using the split method on our function input.
Once we have our function loaded the usage is pretty easy:
>>> c = run('pwd')
>>> c
< subprocess.Popen object at 0x1004a3c50>
Like mentioned above Popen returns a subprocess object, not the result of your command. To access the results and other useful information we are just a method away:
>>> c.communicate()
('/Users/nessy\n', '')
The real beauty I find in using this approach is error handling, something os.system doesn’t provide. Using our object we can check the returncode and validate everything ran cleanly:
>>> c.returncode
0
A return code of 0 is telling us an error was not returned, but what would happen if something did happen:
>>> c = run('ls -ld not_a_file_here.txt')
>>>
>>> c.communicate()
('', 'ls: not_a_file_here.txt: No such file or directory\n')
>>>
>>> c.returncode
1
A return code greater than 0 tells us something went wrong.
Lets see that same command work properly:
>>> c = run('ls -ld Desktop')
>>>
>>> c.communicate()
('drwx------+ 42 nessy staff 1428 Nov 9 10:35 Desktop\n', '')
>>>
>>> c.returncode
0
Now isn’t that slick!
Using this approach you may want to write blocks of commands something like this:
command = 'ls -ld not_a_file_here.txt'
try:
c = run(command)
except OSError as e:
raise(e)
if c.returncode > 0:
print 'Error: we received a return code of %s' % c.returncode
else:
print c.communicate()