1

On a RHEL 6.7 server running Python 2.6.6 I am trying to start and stop the Apache webserver as an unprivileged user in a Python script.

The command I am using is "sudo service httpd " where parameter is "start", "stop" or "status".

p = subprocess.Popen("sudo service httpd start", stdout=subprocess.PIPE, stderr=subprocess.PIPE)

This line alone does not work. Adding a

p.communicate()

lets the commands work as desired. Can somebody tell me why?

UPDATE: The sudoers file contains a line that allows my user to run these commands passwordless.

2 Answers 2

3

Neither code works (with and without .communicate()).

You should use instead (assuming passwordless sudo for these commands):

import subprocess
subprocess.check_call("sudo service httpd start".split())

The reasons:

  1. subprocess functions do not run the shell by default and therefore the string is interpreted as a name of the command: you should use a list to pass multiple command-line arguments on POSIX
  2. Popen() starts the command and returns immediately without waiting for it to finish i.e., it may happen before httpd is started. Assuming Popen() call is fixed, .communicate() waits for the child process to terminate and therefore it returns after httpd is started (whether it was successful or not).
Sign up to request clarification or add additional context in comments.

9 Comments

The code definitely works with .communicate() and does not without. shell=True or shell=Falsemakes no difference in my case. The weird thing for me is why Apache won't stop or start when I do not call .communicate().
@Ronzo: there is no way the code in your question works on a POSIX system such as RHEL. It works if you call .split() as in my answer (or if you pass shell=True that you should not do here).
As I stated above, the code definitely works when I call .communicate() and does not when it is not called. It makes no difference if I call subprocess.Popen(['sudo', 'service', 'httpd', 'start'], Shell=False, ...) or subprocess.Popen('sudo service httpd start', Shell=True, ...)
@Ronzo: do you understand that the code in your question differs from the both variants in your last comment? The code in your question does not work. period. Unrelated: Python is a case-sensitive language. Anyway, copy-paste as is the code from my answer. If you need to discard the output then also use DEVNULL, not PIPE
I posted the code passage from my memory because I was not sitting in front of the machine. The code I am using is: p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) where cmdis the start command with which I am starting various applications on a server. If cmd="sudo service httpd start" it only works after i call p.communicate(). I am aware of case sensitivity and have realized that check_call is a completely different function. I am just wondering why the command to start Apache does not work without calling .communicate().
|
0

There are different reasons for that to happen: 1. the user is in sudoers and configured to not insert password.

  1. sudo remembers your password for some time (depending on your system configuration), see: https://unix.stackexchange.com/questions/37299/how-does-sudo-remember-you-already-entered-roots-password

does it work in a brand new terminal session?

1 Comment

sudoers is configured to allow this command passwordless: myuser ALL = NOPASSWD:/sbin/service httpd * Behaviour is exactly like I wrote above. Without the communicate line the command does not work, with that line it works as desired.

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.