如何用Python Popen做多个参数?

Voi*_*ode 17 python subprocess pygtk popen gnome-terminal

我正在尝试制作一个有按钮的PyGtk Gui.当用户按下此按钮时,gnome-terminal提示用户输入密码.

然后它将为JQuery片段克隆这个Git存储库gedit.

然后,它将js.xml文件复制到/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
Run Code Online (Sandbox Code Playgroud)

它在我的终端工作正常.

但是,通过它刚打开的GUI,我添加了我的密码,按回车键,然后再次关闭.

我只想将命令运行到第一个命令 &&

这是我的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
Run Code Online (Sandbox Code Playgroud)

Dav*_*ain 53

要直接回答您的问题,请阅读以下内容.但是你的程序存在很多问题,其中一些我在"更好的实践"中介绍过.


默认情况下,subprocess.Popen命令作为字符串列表提供.

但是,您也可以使用该shell参数执行命令"格式化,就像在shell提示符下键入时一样."

没有:

>>> p = Popen("cat -n file1 file2")
Run Code Online (Sandbox Code Playgroud)

是:

>>> p = Popen("cat -n file1 file2", shell=True)
>>> p = Popen(["cat", "-n", "file1", "file2"])
Run Code Online (Sandbox Code Playgroud)

这两个选项之间存在许多差异,并且每个选项都有有效的用例.我不会试图总结这些差异 - Popen文档已经做得很好.


所以,对于你的命令,你会做这样的事情:

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)
Run Code Online (Sandbox Code Playgroud)

更好的练习

但是,使用Python作为许多系统命令的包装并不是一个好主意.至少,您应该将命令分解为单独的Popens,以便可以充分处理非零退出.实际上,这个脚本似乎更适合作为shell脚本.但如果你坚持使用Python,那就有更好的做法.

os模块应取代对rm和的调用cp.虽然我没有使用它的经验,但您可能希望查看像GitPython这样的工具来与Git存储库进行交互.

兼容性问题

最后,你应该小心打电话给gnome-terminalsudo.并非所有GNU/Linux用户都运行Ubuntu,并不是每个人都有sudo,或者安装了GNOME终端模拟器.在目前的形式中,如果出现以下情况,您的脚本将崩溃,而无益于此:

  • sudo命令未安装
  • 用户不在该sudoers组中
  • 用户不使用GNOME或其默认终端仿真程序
  • 没有安装Git

如果你愿意假设你的用户正在运行Ubuntu,那么调用x-terminal-emulator是比gnome-terminal直接调用更好的选择,因为它会调用他们安装的任何终端模拟器(例如xfce4-terminal,对于Xubuntu的用户).