我正在尝试制作一个有按钮的PyGtk Gui。当用户按下此按钮时,gnome-terminal
会提示用户输入密码。
然后它将为gedit
JQuery代码段克隆此Git repository。
然后,它将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
在我的终端上工作正常。
但是,通过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
答案 0 :(得分:50)
要直接回答您的问题,请阅读以下内容。但是你的程序存在很多问题,其中一些问题我将在“更好的实践”中介绍。
默认情况下,subprocess.Popen
命令作为字符串列表提供。
但是,您也可以使用shell
参数执行命令“格式化与在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,以便可以充分处理非零退出。实际上,这个脚本似乎更适合作为shell脚本。但如果你坚持使用Python,那就有更好的实践。
os
module应取代rm
和cp
的来电。虽然我没有使用它的经验,但您可能希望查看像GitPython这样的工具来与Git存储库进行交互。
最后,您应该小心拨打gnome-terminal
和sudo
。并非所有GNU / Linux用户都运行Ubuntu,并不是每个人都有sudo
,或者安装了GNOME终端模拟器。在目前的形式中,如果出现以下情况,您的脚本将会崩溃,而无益于此:
sudo
命令sudoers
群组如果您愿意假设您的用户正在运行Ubuntu,那么调用x-terminal-emulator
比直接调用gnome-terminal
更好,因为它会调用他们安装的任何终端模拟器(例如{ {1}}适用于Xubuntu的用户。)