2011-04-01 28 views
15

Estoy escribiendo una aplicación web que usa Selenium para raspar la pantalla de otro sitio web. Este raspado de pantalla solo ocurre una vez al día, así que prefiero no dejar Selenium y Xvfb corriendo todo el tiempo.¿Cómo comienzo y detengo un programa de Linux usando el módulo de subproceso en Python?

Estoy tratando de encontrar la manera de iniciar Xvfb y Selenium desde Python, y luego detenerlos una vez que se haya completado el screen scraping.

Si lo hacía manualmente, me gustaría empezar ellos en la línea de comandos y pulsa CTRL C para detenerlos. Estoy tratando de hacer lo mismo desde Python.

que parecen ser capaces de iniciar correctamente Xvfb así:

xvfb = Popen('Xvfb :99 -nolisten tcp', shell=True) 

Pero cuando he intentado darlo por terminado:

xvfb.terminate() 

y luego trató de empezar de nuevo (repitiendo mi comando inicial), me dice que ya se está ejecutando.

+0

¿Esto obtiene cinco votos favorables? ¡Supuse que solo estaba siendo realmente estúpido! –

+0

Pruebe 'xvfb.wait()' después de 'xvfb.terminate()'. En su defecto, intente 'xvfb.kill()'. –

+3

Ctrl-C envía SIGTERM a un proceso de Unix. Su proceso python de usuario no puede enviar SIGTERM a su Xvfb ejecutándose como root. Obtenga el pid de su hijo, ejecute "sudo kill ", luego "xvfb.wait()". –

Respuesta

7

No sé por qué quieres ejecutar Xvfb como root Su servidor X habitual solo necesita ejecutarse como root (en muchos pero no en todos los unices) solo para que pueda acceder al hardware de video; eso no es un problema para Xvfb por definición.

tempdir = tempfile.mkdtemp() 
xvfb = subprocess.Popen(['Xvfb', ':99', '-nolisten', 'tcp', '-fbdir', tempdir]) 

Al terminar el servidor X, es posible que aparezca un zombie process. De hecho, este no es un proceso (está muerto), solo una entrada en la tabla de procesos que desaparece cuando el proceso principal lee el estado de salida del niño o muere. Los zombis son en su mayoría inofensivos, pero es más limpio llamar al wait para leer el estado de salida.

xvfb.terminate() 
# At this point, `ps -C Xvfb` may still show a running process 
# (because signal delivery is asynchronous) or a zombie. 
xvfb.wait() 
# Now the child is dead and reaped (assuming it didn't catch SIGTERM). 
+0

@Gilles: ah, gotcha - Copié y pegué el comando que uso para iniciar Xvfb desde una página web en algún lado . No me di cuenta de que era la opción 'fbdir' que causaba que no funcionara si no lo ejecutaba como root. Lo eliminé ahora y puedo ejecutarlo como mi usuario habitual, pero '.terminate()' y '.kill()' todavía no parecen detener Xvfb. –

+0

@Paul: Hice un par de errores tipográficos en la llamada 'Popen', pero creo que lo hiciste bien. ¿Estás seguro de que '.terminate()' y '.kill()' no terminan el proceso? Un zombie puede permanecer (desaparecerá cuando finalice tu secuencia de comandos de Python), mira mi edición. – Gilles

+0

@Gilles: Sí, parece que el proceso está dando vueltas. Después de '.terminate()', '.kill()', y después de salir del shell de Python, 'ps -C Xvfb' todavía informa que Xvfb se está ejecutando. Cuando intento iniciar Xvfb nuevamente, también dice que el servidor ya está activo. (Creo que es solo porque el archivo '/ tmp/.X99-lock' todavía existe, pero' ps -C Xvfb' confirma que el proceso todavía se está ejecutando). –

1

supongo que puede parametrizar el sistema para permitir que cualquier usuario pueda lanzar Xvfb como se explica here resolver todos sus problemas

EDITAR la línea de comandos es correcta

sudo chmod u+s `which Xvfb` 
+0

Podría ser - ¿qué parte de eso permite a cualquier usuario ejecutar Xvfb sin embargo? ¿Es 'sudo mod u + s' que Xvfb''? No estoy familiarizado con el comando 'mod', y es algo inmune a Google, ¿podría ampliarlo? –

+0

de hecho debería ser 'chmod u + s' como se explica aquí http://en.wikipedia.org/wiki/Chmod –

+0

Dudo que el comando' mod' exista para tener ayuda sobre un comando simplemente escriba 'man command ' –

Cuestiones relacionadas