14

I've written hello.py (a basic "hello world" program) and would like to be able to quickly run it on my Ubuntu machine by pressing the Win key to open Dash, then type the name of the script (or something similar to that).

However, when I type hello.py into Dash, it opens the file in an editor rather than execute it. I added a shebang line #!/usr/bin/env python3 and run chmod u+x hello.py, it still opens the file in an editor.

I tried creating a hello.sh shell script that will run the Python script, but the shell script also gets opened in the editor when I type its name into Dash.

Also, I tried pressing Alt-F2 and it brings up something like Windows' Win-R, but when I enter python3 hello.py it doesn't bring up a terminal window to display any print() output.

Is there a way to run a Python script by typing its name into Dash? Or is there another easy way to run an arbitrary Python script? Essentially, what I want is something like the Windows Run Dialog Box that appears when you press Win-R, which can run any program on the system PATH.

Al Sweigart
  • 11,566
  • 10
  • 64
  • 92
  • I dont think you can launch python script from ubuntu dash like this. Correct me if I am wrong but the way you are trying to do it, Ubuntu dash will try to find default application to open `*.py` files which generally will be a text editor. You need to make something like `hello_world.desktop` which in turn should contain directive to execute `hello_world.py`. Take a look at this which might help you https://askubuntu.com/a/64237 – Paandittya Mar 16 '19 at 06:29
  • see https://gist.github.com/nathakits/7efb09812902b533999bda6793c5e872 – Alex_Krug Mar 17 '19 at 05:43
  • I am missing something here. If I start *dash* (*/usr/bin/dash*) in a terminal, and launch the script (in all the forms you mentioned), I get the correct results. Could you add more details (maybe a screenshot)? – CristiFati Aug 30 '19 at 11:39
  • I don't have /usr/bin/dash, but I do have a /bin/dash. However, when I run that I just get a new bash-like $ prompt. By "Ubuntu Dash" I mean the Start Menu-like user interface that appears when you press the Windows key: https://askubuntu.com/questions/299295/what-is-the-dash#299297 – Al Sweigart Aug 30 '19 at 17:11

4 Answers4

9

(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)
Bengerman
  • 821
  • 7
  • 7
  • I saved this as hello.desktop (I assume that's the file extension I should use) but it doesn't appear when I type "hello" into Dash. Doing chmod +x on hello.desktop doesn't help. – Al Sweigart Aug 29 '19 at 05:41
  • I made a couple edits that might help - specifically about forcing it to the foreground – Bengerman Aug 29 '19 at 05:46
  • one quick guess: `~/hello.py` does not work, but `/home/ben/hello.py` does – Bengerman Aug 29 '19 at 06:07
  • Unfortunately, it's not the ~ issue. The hello.desktop file simply doesn't show up in Dash; it just says "No results." after I type "hello" or "hello.desktop". – Al Sweigart Aug 29 '19 at 06:22
  • The keyword dash wants is the value of the `Name` field. If it's not showing up, that's probably a sign that the syntax of the file is wrong. – Bengerman Aug 29 '19 at 06:52
  • I can find it in Dash now however when I run it, it doesn't display the terminal. It runs in the background (I can see output it makes to a logging file) but a new terminal window for print() output doesn't appear anywhere. Is there something else I need to do besides gnome-terminal -- /path/to/hello.py? Does this work on your machine? – Al Sweigart Aug 30 '19 at 17:20
  • 1
    Ah, I think the problem is that the window disappears as soon as the Python script finishes. You have to either add a `input('Press any key to continue')` at the end, or have the .desktop file run a shell script that runs bash afterwards to keep the window open. I'll modify this answer correctly and accept it so you get the bounty. Thanks! – Al Sweigart Aug 30 '19 at 17:24
  • Updated documentation [link](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html). Review queue currently full :/ – topher217 Jul 29 '22 at 02:47
3

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:

  1. [FreeDesktop.Specifications]: Desktop Entry Specification
  2. [Lifewire]: The Complete Guide to the Ubuntu Unity Dash
  3. [AskUbuntu]: Creating a .desktop file for a new application
  4. [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))
  5. 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
    • Outer: Used to wrap the inner one, as the parser doesn't like redirect operator

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

    Img0

    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:

    Img1

  • 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).

CristiFati
  • 38,250
  • 9
  • 50
  • 87
1

Using the gnome-panel GUI is probably the easiest way:

  1. Install gnome-panel.

    $ sudo apt install gnome-panel
    
  2. 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
    

enter image description here

  1. Fill out the launcher details.

enter image description here

  1. Then you'll have access to the icon from the launcher and can move it to the desktop or where ever you need it.

enter image description here

  1. 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.

enter image description here

Holden Rehg
  • 917
  • 5
  • 10
0

Regarding your last paragraph:

Is there a way to run a Python script by typing its name into Dash? Or is there another easy way to run an arbitrary Python script? Essentially, what I want is something like the Windows Run Dialog Box that appears when you press Win-R, which can run any program on the system PATH.

You almost answer yourself. In Linux you also have a PATH environment variable. You can check it in a console typing:

$ echo $PATH

I have my path edited in my /home/xbello/.bashrc file to something like this:

export PATH=$HOME/bin:$PATH

Now I put my programs and scripts in /home/xbello/bin, chmod them to +x, and they are always available from a terminal or an Alt+F2. You don't need the extension if you add the shebang #!/bin/env python. The problem is that the output of a print("Hello world") executed from an Alt+F2 is gonna be lost. You need some code like this:

#!/bin/env python3
import os

os.system("notify-send 'Hello world'")
xbello
  • 7,223
  • 3
  • 28
  • 41
  • Yes, but this is running them from a terminal window, not running them from Dash. Or in the case of Alt-F2, it runs the script without opening a terminal window to display the output. I'm looking for a one-step solution. – Al Sweigart Sep 02 '19 at 17:47
  • You can open a terminal with e.g. os.system("terminal -e 'echo Hello world; sleep 2'"), changing `terminal` for your preferred terminal (gnome-terminal, lxterminal, etc). The good part of this is that you have your command available from terminal, Alt+F2 and Dash. – xbello Sep 03 '19 at 09:05