user1618238
user1618238

Reputation: 29

How do I run a command in background using commands module in python?

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

Answers (4)

Eric Leschinski
Eric Leschinski

Reputation: 154063

Running processes in the background using Python 2.7

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

amoffat
amoffat

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

Fred Foo
Fred Foo

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

Andrew Clark
Andrew Clark

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

Related Questions