Как сделать несколько аргументов с Python Popen?

Я пытаюсь сделать графический интерфейс PyGtk, у которого есть кнопка. Когда пользователь нажимает эту кнопку, gnome-terminal предлагает пользователю написать свой пароль.

тогда он будет клонировать это репозиторий Git на gedit сниппетов на jQuery.

и затем он копирует до /usr/share/gedit/plugins/snippets/js.xml

в конце концов, он принудительно удаляет репозиторий Git.

команды:

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

он отлично работает на моем терминал.

а, через GUI он просто открывается, я добавляю свой пароль, нажмите enter, а затем он снова закрывается.

Я хотел бы выполнить команду только до первого &&

это моя функция Python (с командой):

    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

1 ответов


чтобы напрямую ответить на ваш вопрос, читайте ниже. Но есть много проблем с вашей программой, некоторые из которых я освещаю в "лучшей практике"."


по умолчанию subprocess.Popen команды предоставляются в виде списка строк.

однако вы также можете использовать shell аргумент для выполнения команды " отформатирован точно так же, как это было бы при вводе в оболочке быстрый."

нет:

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

да:

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

существует ряд различий между этими двумя вариантами и допустимыми вариантами использования для каждого из них. Я не буду пытаться суммировать различия -Popen docs уже делают отличную работу.


Итак, в случае ваших команд, вы бы сделали что-то вроде этого:

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)

лучше практика

однако использование Python в качестве оболочки для многих системных команд не очень хорошая идея. По крайней мере, вы должны разбивать свои команды на отдельные Popens, чтобы ненулевые выходы можно было обрабатывать адекватно. На самом деле, этот сценарий кажется, что он гораздо лучше подходит в качестве сценария оболочки. Но если вы настаиваете на Python, есть лучшие практики.

на os модуль должно занять место звонков в rm и cp. И хотя у меня нет опыта в этом, вы можете посмотреть на такие инструменты, как GitPython для взаимодействия с репозиториями Git.

проблемы совместимости

наконец, вы должны быть осторожны при совершении звонков в gnome-terminal и sudo. Не все пользователи GNU/Linux запускают Ubuntu, и не у всех есть sudo или установлен эмулятор терминала GNOME. В своей текущей форме ваш скрипт рухнет, довольно бесполезно, если:

  • на sudo команда не установлена
  • пользователь не находится в sudoers группа
  • пользователь не использует GNOME или эмулятор терминала по умолчанию
  • Git не установлен

если вы готовы предположить, что ваши пользователи работают Ubuntu, вызывая x-terminal-emulator - это гораздо лучший вариант, чем вызов gnome-terminal напрямую, как он будет называть любой эмулятор терминала, который они установили (например,xfce4-terminal для пользователей Xubuntu).