2009-02-19 6 views
33

Por lo tanto, estoy tratando de ejecutar un proceso como superusuario dentro de una secuencia de comandos python utilizando subprocesos. En el shell ipython algo así comoejecutando un comando como superusuario desde una secuencia de comandos python

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

trabaja muy bien, pero tan pronto como lo pego en un guión que comienza a recibir: sudo: apach2ctl: command not found.

Supongo que esto se debe a la forma en que sudo maneja los entornos en ubuntu. (También he intentado sudo -E apche2ctl restart y sudo env path=$PATH apache2ctl restart sin resultado)

Así que mi pregunta es, básicamente, si quiero correr apache2ctl restart como super usuario que solicita al usuario la contraseña de superusuario cuando sea necesario, ¿cómo debo ir haciendo ¿esta? No tengo intención de almacenar contraseñas en el script.

Editar:

He intentado pasar en los comandos tanto como una cadena y tokenizados en una lista. En el intérprete de Python, con una cadena obtendré la solicitud de contraseña correctamente (todavía no funciona en un script de Python como en mi problema original), una lista solo da la pantalla de ayuda para sudo.

Edición 2:

Así que lo que tengo entendido es que mientras Popen trabajará con algunos comandos simplemente como cadenas cuando el shell = True, se necesita

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

sin 'shell = True' para obtener sudo trabajar.

Gracias!

+2

¿Qué hay de la configuración de sudo para que este usuario pueda ejecutar solo este comando sin necesidad de una contraseña? –

+0

Es posible que desee usar ['proc.wait()'] (https://docs.python.org/2/library/subprocess.html#subprocess.Popen.wait) según lo que esté haciendo; 'wait' no continúa hasta que el proceso hijo haya terminado de ejecutarse. – craymichael

Respuesta

14

Intenta dar la ruta completa a apache2ctl.

+0

Creo que lo has golpeado. La ejecución de un script del intérprete hereda $ PATH del shell interactivo que lo está ejecutando. Sin embargo, cuando se ejecuta como un script, $ PATH se hereda de un shell NO interactivo y puede no ser el mismo. Lo mejor es especificar siempre las rutas completas cuando se usa popen(). –

+0

Sí, siempre que haga referencia a los binarios de las secuencias de comandos, no puede confiar en que $ PATH esté ahí para usted. Por cierto, "apch2ctl" está mal escrito. ;) – ojrac

3

usted tiene que utilizar Popen así:

cmd = ['sudo', 'apache2ctl', 'restart'] 
proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 

Se espera que una lista.

+7

Leer http://docs.python.org/library/subprocess.html Hay una diferencia entre una cadena y secuencias args cuando shell = True. – jfs

+0

Ah, ya veo, nunca lo había usado así antes. –

+1

No establecer shell = True cuando está pasando una lista en él. –

21

Probar:

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

El subproceso necesita acceder a la verdadera entrada estándar de entrada/salida/err para que sea capaz de incitar usted, y leer en su contraseña. Si los configura como tubos, necesita alimentar la contraseña en esa tubería usted mismo.

Si no se define, entonces se agarra sys.stdout, etc ...

7

Otra forma es hacer que su usuario una contraseña de menos sudo user.

Escriba lo siguiente en la línea de comandos:

sudo visudo 

A continuación, añada lo siguiente y vuelva a colocar la <username> con la suya:

<username> ALL=(ALL) NOPASSWD: ALL 

Esto permitirá al usuario ejecutar sudo comando sin tener que pedir contraseña (incluida la aplicación iniciada por dicho usuario).Esto podría ser un riesgo de seguridad, aunque

Cuestiones relacionadas