How to make multiple arguments using Python Popen?

I am trying to create a PyGtk Gui that has a button. When the user clicks this button, gnome-terminal prompts the user to write down his password.

He will then clone this Git repository for gedit jQuery snippets.

And then it copies the js.xml file to /usr/share/gedit/plugins/snippets/js.xml

In the end, it forcibly deletes the Git repository.

Command:

 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 

It works great in my terminal.

But through the GUI, it just opens, I add my password, press Enter, and then close again.

I only want to run the command for the first &&

This is my Python function (with command):

  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 
+6
source share
1 answer

To answer your question, read below. But you have a lot of problems with your program, some of which I cover in Best Practice.


By default, subprocess.Popen commands are supplied as a list of strings.

However, you can also use the shell argument to execute the command "formatted exactly the same as it would be when typed on the command line."

not

Not:

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

Yes:

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

There are several differences between the two options and the actual use cases for each. I will not try to summarize the differences - Popen docs already does a great job of this.


So, in the case of your commands, you would do something like this:

 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) 

Best practice

However, using Python as a shell for many system commands is actually not a good idea. At the very least, you should split your commands into separate Popens, so non-zero outputs can be handled appropriately. Actually this script seems to be much better suited as a shell script. But if you insist on Python, there are best practices.

The os module should replace the calls with rm and cp . And although I have no experience with it, you can look at tools like GitPython to interact with Git repositories.

Compatibility issues

Finally, you have to be careful when calling gnome-terminal and sudo . Not all GNU / Linux users run Ubuntu, and not everyone has sudo , or the GNOME terminal emulator is installed. In its current form, your script will crash, and not useless if:

  • sudo not installed
  • User is not in sudoers group
  • User does not use GNOME or its default terminal emulator
  • Git not installed

If you agree that your users are running Ubuntu, calling x-terminal-emulator much better than calling gnome-terminal directly, as it will call any terminal emulator that they installed (e.g. xfce4-terminal for Xubuntu users).

+34
source

Source: https://habr.com/ru/post/919436/


All Articles