J'essaie de faire un PyGtk Gui, qui a un bouton. Lorsque l'utilisateur appuie sur ce bouton, gnome-terminal
invite l'utilisateur à écrire son mot de passe.
Ensuite, il clonera ce référentiel Git pour gedit
extraits JQuery.
Et puis, il copie le js.xml
fichier vers /usr/share/gedit/plugins/snippets/js.xml
En fin de compte, il supprime de force le référentiel Git.
La commande:
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
Cela fonctionne bien dans mon terminal.
Mais, via l'interface graphique, il vient d'ouvrir, j'ajoute mon mot de passe, appuyez sur Entrée, puis il se referme.
Je souhaite exécuter la commande uniquement sur le premier &&
Ceci est ma Python (avec commande):
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
Pour répondre directement à votre question, lisez ci-dessous. Mais il y a beaucoup de problèmes avec votre programme, dont certains que je couvre dans "Better practice".
Par défaut, subprocess.Popen
les commandes sont fournies sous forme de liste de chaînes.
Cependant, vous pouvez également utiliser l'argument Shell
pour exécuter une commande "formatée exactement comme elle le serait lors de la frappe à l'invite du shell".
Non:
>>> p = Popen("cat -n file1 file2")
Oui:
>>> p = Popen("cat -n file1 file2", Shell=True)
>>> p = Popen(["cat", "-n", "file1", "file2"])
Il existe un certain nombre de différences entre ces deux options et des cas d'utilisation valides pour chacune. Je n'essaierai pas de résumer les différences - les Popen
docs font déjà un excellent travail.
Donc, dans le cas de vos commandes, vous feriez quelque chose comme ceci:
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)
Cependant, utiliser Python comme wrapper pour de nombreuses commandes système n'est pas vraiment une bonne idée. À tout le moins, vous devriez diviser vos commandes en Popens séparés, afin que les sorties non nulles puissent En réalité, ce script semble être beaucoup mieux adapté en tant que script Shell. Mais si vous insistez sur Python, il existe de meilleures pratiques.
Le module os
devrait remplacer les appels à rm
et cp
. Et même si je n'ai aucune expérience avec cela, vous voudrez peut-être regarder des outils comme GitPython pour interagir avec les référentiels Git.
Enfin, vous devez faire attention à ne pas appeler gnome-terminal
et Sudo
. Tous les utilisateurs GNU/Linux n'exécutent pas Ubuntu, et tout le monde n'a pas Sudo
, ou l'émulateur de terminal GNOME installé. Dans sa forme actuelle, votre script se bloquera, de façon plutôt inutile, si:
Sudo
n'est pas installéesudoers
Si vous êtes prêt à supposer que vos utilisateurs exécutent Ubuntu, appelez x-terminal-emulator
est une bien meilleure option que d'appeler gnome-terminal
directement, car il appellera l'émulateur de terminal installé (par exemple xfce4-terminal
pour les utilisateurs de Xubuntu).