running a command as a super user from a python script

Silfheed picture Silfheed · Feb 19, 2009 · Viewed 120.2k times · Source

So I'm trying to get a process to be run as a super user from within a python script using subprocess. In the ipython shell something like

proc = subprocess.Popen('sudo apach2ctl restart',
                        shell=True, stdin=subprocess.PIPE,
                        stdout=subprocess.PIPE,
                        stderr=subprocess.PIPE)

works fine, but as soon as I stick it into a script I start getting: sudo: apach2ctl: command not found.

I would guess this is due to the way sudo handles environments on ubuntu. (I've also tried sudo -E apche2ctl restart and sudo env path=$PATH apache2ctl restart with no avail)

So my question is basically, if I want to run apache2ctl restart as super user that prompts the user for the super user password when required, how should I go about doing this? I have no intention of storing passwords in the script.

Edit:

I've tried passing in the commands as both a string and tokenized into a list. In the python interpreter, with a string I'll get the password prompt properly (still doesnt work in a python script as in my original problem), a list just gives the help screen for sudo.

Edit 2:

So what I gather is that while Popen will work with some commands just as strings when shell=True, it takes

proc = subprocess.Popen(['sudo','/usr/sbin/apache2ctl','restart'])

without 'shell=True' to get sudo to work.

Thanks!

Answer

Mike Boers picture Mike Boers · Feb 20, 2009

Try:

subprocess.call(['sudo', 'apach2ctl', 'restart'])

The subprocess needs to access the real stdin/out/err for it to be able to prompt you, and read in your password. If you set them up as pipes, you need to feed the password into that pipe yourself.

If you don't define them, then it grabs sys.stdout, etc...