¿Cómo hacer múltiples argumentos con Python Popen?

Estoy tratando de hacer una Gui PyGtk, que tiene un botón. Cuando el usuario presiona este botón, gnome-terminal solicita al usuario que escriba su contraseña.

Luego clonará este repository Git para los fragmentos de gedit JQuery gedit .

Y luego, copia el archivo js.xml a /usr/share/gedit/plugins/snippets/js.xml

Al final, elimina con fuerza el repository de Git.

El comando:

 gnome-terminal -x sudo git clone git://github.com/pererinha/gedit-snippet-jquery.git && sudo cp -f gedit-snippet-jquery/js.xml /usr/share/gedit/plugins/snippets/js.xml && sudo rm -rf gedit-snippet-jquery 

Funciona bien en mi terminal.

Pero, a través de la GUI, simplemente se abre, agrego mi contraseña, presiono la tecla Intro y luego se cierra nuevamente.

Me gustaría ejecutar solo el comando a la primera &&

Esta es mi función de Python (con comando):

  def on_install_jquery_code_snippet_for_gedit_activate(self, widget): """ Install Jquery code snippet for Gedit. """ cmd="gnome-terminal -x sudo git clone git://github.com/pererinha/gedit-snippet-jquery.git && sudo cp -f gedit-snippet-jquery/js.xml /usr/share/gedit/plugins/snippets/js.xml && sudo rm -rf gedit-snippet-jquery" p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=False) self.status.set_text(p.stdout.read()) #show response in 'status 

Para responder directamente a su pregunta, lea a continuación. Pero hay muchos problemas con su progtwig, algunos de los cuales cubro en “Mejores prácticas”.


De forma predeterminada, los comandos subprocess.Popen se suministran como una lista de cadenas.

Sin embargo, también puede usar el argumento de shell para ejecutar un comando “con el formato exacto tal como sería cuando se escribiera en el indicador del shell”.

No:

 >>> p = Popen("cat -n file1 file2") 

Sí:

 >>> p = Popen("cat -n file1 file2", shell=True) >>> p = Popen(["cat", "-n", "file1", "file2"]) 

Hay una serie de diferencias entre estas dos opciones y casos de uso válidos para cada una. No intentaré resumir las diferencias: los documentos de Popen ya hacen un excelente trabajo de eso.


Entonces, en el caso de tus comandos, harías algo como esto:

 cmd = "gnome-terminal -x sudo git clone git://github.com/pererinha/gedit-snippet-jquery.git && sudo cp -f gedit-snippet-jquery/js.xml /usr/share/gedit/plugins/snippets/js.xml && sudo rm -rf gedit-snippet-jquery" p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=False) 

Mejor practica

Sin embargo, usar Python como envoltorio para muchos comandos del sistema no es realmente una buena idea. Como mínimo, debe dividir sus comandos en Popens separados, de modo que las salidas que no sean cero puedan manejarse adecuadamente. En realidad, esta secuencia de comandos parece que sería mucho más adecuada como una secuencia de comandos de shell. Pero si insistes en Python, hay mejores prácticas.

El módulo os debe tomar el lugar de las llamadas a rm y cp . Y aunque no tengo experiencia con esto, es posible que desee ver herramientas como GitPython para interactuar con los repositorys de Git.

Preocupaciones de compatibilidad

Por último, debes tener cuidado al hacer llamadas a gnome-terminal y sudo . No todos los usuarios de GNU / Linux ejecutan Ubuntu, y no todos tienen sudo , o el emulador de terminal de GNOME instalado. En su forma actual, su script se bloqueará, de manera poco útil, si:

  • El comando sudo no está instalado
  • El usuario no está en el grupo sudoers
  • El usuario no usa GNOME, o su emulador de terminal predeterminado
  • Git no está instalado

Si está dispuesto a asumir que sus usuarios están ejecutando Ubuntu, llamar a x-terminal-emulator es una opción mucho mejor que llamar a gnome-terminal directamente, ya que llamará a cualquier emulador de terminal que hayan instalado (por ejemplo, xfce4-terminal para usuarios de Xubuntu).