How can I run a Python script from Ubuntu Dash?
I want to start by pointing out that I'm not a Lnx UI expert (it's not my main environment, and I mostly work without X). But I guess that was obvious from my comment. So I had to Google. Some resources:
- [FreeDesktop.Specifications]: Desktop Entry Specification
- [Lifewire]: The Complete Guide to the Ubuntu Unity Dash
- [AskUbuntu]: Creating a .desktop file for a new application
- [GNOME.Developer]: Desktop files: putting your application in the desktop menus (also pointed out by [SO]: How can I run a Python script from Ubuntu Dash? (@Bengerman's answer))
- Many others
The solution is similar to @Bengerman's (which is normal, as .desktop files are the most common way of customizing Dash).
People can look at it as if it was either:
- A neat trick
- A lame workaround (gainarie)
I too, am oscillating between the 2, but given the fact that Dash was probably not designed to work this way, I'm kinda leaning towards the latter.
1. Setup (system info)
I have a VirtualBox VM with the following specs:
cfati@cfati-ubtu16x64-0:~/bin$ ~/sopr.sh *** Set shorter prompt to better fit when pasted in StackOverflow (or other) pages *** [064bit prompt]> uname -a Linux cfati-ubtu16x64-0 4.15.0-58-generic #64~16.04.1-Ubuntu SMP Wed Aug 7 14:10:35 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux [064bit prompt]> [064bit prompt]> cat /etc/lsb-release | grep LTS DISTRIB_DESCRIPTION="Ubuntu 16.04.6 LTS" [064bit prompt]> [064bit prompt]> cat /etc/X11/default-display-manager /usr/sbin/lightdm [064bit prompt]> [064bit prompt]> echo ${PATH} /home/cfati/bin:/home/cfati/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/cfati/Install/Google/Android_SDK/tools:/home/cfati/Install/Google/Android_SDK/platform-tools:/home/cfati/Install/Google/Android_SDK/ndk-bundle:/home/cfati/Install/Google/Android_SDK/tools:/home/cfati/Install/Google/Android_SDK/platform-tools:/home/cfati/Install/Google/Android_SDK/ndk-bundle [064bit prompt]> [064bit prompt]> ls -l ~/.local/share/applications/py.desktop -rw-r--r-- 1 cfati cfati 400 aug 30 20:22 /home/cfati/.local/share/applications/py.desktop [064bit prompt]> [064bit prompt]> ls -l total 4 -rwxrwxr-x 1 cfati cfati 142 aug 30 21:49 hwx.py
So, it's an Ubtu 16 x64, with Unity.
2. Create the .desktop application
py.desktop:
[Desktop Entry]
Name=Generic Python file
Comment=Run a Python file when typing its name in Dash ...
Exec=bash -c "bash --rcfile <(echo \"/usr/bin/env python3 %F\")"
#Icon will differ on other machines.
Icon=/usr/share/pixmaps/python3.5.xpm
Terminal=true
Type=Application
#I am not fully aware of the following entries implications
Categories=ConsoleOnly;Utility;System;Development;
Keywords=console;python;
Copy the above file in ${HOME}/.local/share/applications (only enable for current user).
Notes:
- When opening Dash, it should appear under Applications. However, it might take some time to appear there. While I was editing it, I noticed that sometimes it failed to appear (many of those were because its content was invalid (I was in the learning process), but there were a few that I can't explain)
- Exec key - bash:
- Inner: used to launch Python, and don't exit when Python does
- Launching Python has 2 implications regarding shebangs:
- Will be ignored (for files that have them)
- Files that don't have them will work as well
- Launching Python has 2 implications regarding shebangs:
- Outer: Used to wrap the inner one, as the parser doesn't like redirect operator
- Inner: used to launch Python, and don't exit when Python does
2.1. Associate .py files with the new application
On my UI, I had to:
- Right click on a .py file
- Go to Properties -> Open With
- Select Generic Python file from the applications list (might have to Add it if it doesn't show)
- Check Set as default button
3. Test
Test file is located in ~/bin (which is in ${PATH}).
hwx.py:
#!/usr/bin/env python3
import sys
import os
print("Hello World from: [{0:s}]".format(os.path.abspath(__file__)))
input("Press <ENTER>: ")
Open Dash and type the file name
Note: Don't know whether it's a glitch on my VM, or it's something general, but sometimes I have to also type a SPACE after the file name (it's visible in the picture as well), in order for the options to appear
Select (click on) the file from the options displayed below, and a console will open:
Needless to say that after the Python process will exit, the console will remain
Not relevant to the question, but I think it is worth mentioning [SO]: How do I set “default App” for a file extension to an “.exe” on Windows 10 after April 2018 update (@CristiFati's answer).
(Tested on 18.04)
Create this file in ~/.local/share/applications
(for use only by your user) or in /usr/share/applications
(for use by all users).
The file name must end in .desktop.
[Desktop Entry]
Name=hello.py
Exec=/path/to/hello.py
Type=Application
Categories=GTK;GNOME;Utility;
Note that the script runs in the background, and errors are swallowed unless you configure logging to a file within your script.
If you want it to run in a console, you could do this (the console will close when the script exits, though):
[Desktop Entry]
Name=hello.py
Exec=gnome-terminal -- /path/to/hello.py
Type=Application
Categories=GTK;GNOME;Utility;
More features are available if you want icons, to limit what desktop environments it runs under, etc - docs here: https://developer.gnome.org/integration-guide/stable/desktop-files.html.en
assumptions:
- hello.py is executable by the current user
- hello.py has a valid shebang
- the path needs to be an absolute path (i.e. not relative and also not using shell expansions such as ~ or variables)
Using the gnome-panel
GUI is probably the easiest way:
Install
gnome-panel
.$ sudo apt install gnome-panel
Launch the item edit script. You'll need to put the
.desktop
file in either~/.local/share/applications
or in/usr/share/applications
. Keep in mind that/usr/share
will be accessible to all system users.$ gnome-desktop-item-edit --create-new ~/.local/share/applications/Tester.desktop
- Fill out the launcher details.
- Then you'll have access to the icon from the launcher and can move it to the desktop or where ever you need it.
If you ever need to edit the application, you have 2 options:
a. Run the item edit script again to reopen the GUI.
```shell $ gnome-desktop-item-edit ~/.local/share/applications/Tester.desktop ```
b. Open up the Desktop file directly in something like
vim
.