Reputation: 29
I want to run a system command in the background using python 2.7, this is what I have:
import commands
path = '/fioverify.fio'
cmd= "/usr/local/bin/fio" + path + " "+ " &"
print cmd
handle = commands.getstatusoutput(cmd)
This fails. If I remove the ampersand &
it works. I need to run a command (/usr/local/bin/fio/fioverifypath
) in the background.
Any pointers on how to accomplish this?
Upvotes: 1
Views: 2694
Reputation: 154063
commands.getstatusoutput(...)
isn't smart enough to handle background processes, use subprocess.Popen
or os.system
.
Reproducing the error of how commands.getstatusoutput
fails on background processes:
import commands
import subprocess
#This sleeps for 2 seconds, then stops,
#commands.getstatus output handles sleep 2 in foreground okay
print(commands.getstatusoutput("sleep 2"))
#This sleeps for 2 seconds in background, this fails with error:
#sh: -c: line 0: syntax error near unexpected token `;'
print(commands.getstatusoutput("sleep 2 &"))
A demo of how subprocess.Popen succeeds on background processes:
#subprocess handles the sleep 2 in foreground okay:
proc = subprocess.Popen(["sleep", "2"], stdout=subprocess.PIPE)
output = proc.communicate()[0]
print(output)
#alternate way subprocess handles the sleep 2 in foreground perfectly fine:
proc = subprocess.Popen(['/bin/sh', '-c', 'sleep 2'], stdout=subprocess.PIPE)
output = proc.communicate()[0]
print("we hung for 2 seconds in foreground, now we are done")
print(output)
#And subprocess handles the sleep 2 in background as well:
proc = subprocess.Popen(['/bin/sh', '-c', 'sleep 2'], stdout=subprocess.PIPE)
print("Broke out of the sleep 2, sleep 2 is in background now")
print("twiddling our thumbs while we wait.\n")
proc.wait()
print("Okay now sleep is done, resume shenanigans")
output = proc.communicate()[0]
print(output)
A demo of how os.system can handle background processes:
import os
#sleep 2 in the foreground with os.system works as expected
os.system("sleep 2")
import os
#sleep 2 in the background with os.system works as expected
os.system("sleep 2 &")
print("breaks out immediately, sleep 2 continuing on in background")
Upvotes: 0
Reputation: 714
You can also try sh.py, it has support for background commands:
import sh
bin = sh.Command("/usr/local/bin/fio/fioverify.fio")
handle = bin(_bg=True)
# ... do other code ...
handle.wait()
Upvotes: 0
Reputation: 363767
Don't use commands
; it's deprecated and not actually useful for your purposes. Use subprocess
instead.
fio = subprocess.Popen(["/usr/local/bin/fio", path])
runs the fio
command in parallel with your process and binds the variable fio
to a handle to the process. You can then call fio.wait()
to wait for the process to finish and retrieve its return status.
Upvotes: 2
Reputation: 208575
Use the subprocess module, subprocess.Popen
allows you to run a command as a subprocess (in the background) and check its status.
Upvotes: 0