5

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.

3
  • possible duplicate of Launch a shell command with in a python script, wait for the termination and return to the script Commented May 5, 2014 at 16:02
  • I do NOT want to wait for termination. I want to delay the execution of the command and exit the python script. Then I want the command to get executed, 10 seconds after the python script has exited. Commented May 5, 2014 at 16:06
  • Yes, it is still the same problem. You do NOT need to wait. All you need is shell = True. Commented May 5, 2014 at 16:10

2 Answers 2

7

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.