fredrik
fredrik

Reputation: 10281

Execute command with delay using subprocess

I'm trying to execute this command from a python script using subprocess: sleep 10 && sudo /etc/init.d/tractor-blade restart &

I want the python script to finish (return code 0). Then, 10 seconds later I wish the command to get executed.

This is what I have:

import sys, subprocess
command = ['sleep', '10', '&&', 'sudo', '/etc/init.d/tractor-blade', 'restart' '&']
p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

# Catch stdout
sys.stdout.flush()
for line in iter(p.stdout.readline, b''):
    print(">>> " + line.rstrip())

But this is what happens:

>>> sleep: invalid time interval `&&'
>>> sleep: invalid time interval `sudo'
>>> sleep: invalid time interval `/etc/init.d/tractor-blade'
>>> sleep: invalid time interval `restart'
>>> sleep: invalid time interval `&'
>>> Try `sleep --help' for more information.

I am guessing my formatting is wrong?

I need to make the python script complete before the command is being executed, which is why I am trying to add a delay to the command. My sudoers allows for this `tractor-blade' to get executed with NOPASSWD, thus does not require a password.

Upvotes: 5

Views: 10434

Answers (2)

zmo
zmo

Reputation: 24812

this is because subprocess can work in two modes: either you fork() the process specified by the tuple passed as argument, or you execute the string with a shell. The difference is the shell argument. So what you might want to do is:

command = "sleep 10 && sudo /etc/init.d/tractor-blade restart"
p = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT)

or:

time.sleep(10)
command = ['sudo', '/etc/init.d/tractor-blade', 'restart' '&']
subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

from the documentation:

The shell argument (which defaults to False) specifies whether to use the shell as the program to execute. If shell is True, it is recommended to pass args as a string rather than as a sequence.

Upvotes: 7

Santa
Santa

Reputation: 11547

The way the API works is, the first element in command is the program that subprocess.Popen will invoke. And the rest of that list is parsed and then fed into that program as arguments. By default, they are not parsed as a shell command.

Upvotes: 0

Related Questions