14

How to run a Python program directly?

I have created a .py file (say, mnik.py) in gedit. It runs smoothly in terminal.

Command goes

python3 mnik.py

But whenever I click on the file it is opened with gedit. I cannot run it directly by clicking.

What to do?

vaultah
  • 105
  • 5
  • 2
  • Typing python3 on the command line is not the proper way to run a Python script. You should be invoking it as ./mnik.py or if it is in your PATH you could simply type mnik.py. Apart from that, there is an excellent answer below detailing the rest you need to do. – kasperd Apr 23 '16 at 21:37
  • 4
    @kasperd Typing python3 on the command line with an argument is an excellent way to run python scripts. It is in fact the easiest way to run a program that requires a terminal and arguments (like many of my own scripts, but also programs like mercurial, sphinx). Care to explain why what I have been doing for 20+ years is not the proper way? – Anthon Apr 24 '16 at 07:58
  • @Anthon A correctly written script has a #! line at the start specifying which interpreter to use. When you type the interpreter name on the command line you might not notice if you made a mistake in creating the script. It also means there is a risk you mistakenly type the incorrect interpreter, which is a risk there is no reason to take. Finally it is shorter to type ./mnik.py than to type python3 mnik.py. – kasperd Apr 24 '16 at 09:03
  • 3
    @kasperd A correct written Python script (or program) doesn't have to have a shebang line. If it doesn't it is still a Python script in every way. That script just cannot be executed by from the Linux shells in the short-hand form you seem to prefer. There are also environments that don't require Python scripts to have a shebang line at all and allow them to start the script by double clicking. – Anthon Apr 24 '16 at 09:20
  • @Anthon The kernel will refuse to execute a script without the #! line. If you type strace ./mnik.py and the script has no #! line, you will see the error. The error code is ENOEXEC, which translates to Exec format error. There are workarounds to run a badly formatted script, but you should not rely on workarounds, when you have the option to do things right. – kasperd Apr 24 '16 at 09:26
  • @Anthon For testing I just created a "Python script" with only the single line print "Hello world". This may work just fine if you always use the same workaround. But sooner or later somebody will not know about your preferred workaround, and will try to execute the script the way a script is intended to be executed. It happens to be the case that bash has its own workaround, which is different from yours. And the error I get is this: Warning: unknown mime-type for "Hello world" -- using "application/octet-stream" Error: no such file "Hello world" – kasperd Apr 24 '16 at 09:34
  • 1
    @kasperd What the kernel needs in order for a Python script to run using ./scriptname doesn't validate your claim that running a script from the commandline by using python3. There are different ways of running python scripts and doing python3 ./mnik.py is also a proper way of doing things, it is just different (and at least you get python3 that way and not python2 as is more likely with the most the answers so far) – Anthon Apr 24 '16 at 09:34
  • 2
    Using – Jacob Vlijm Apr 24 '16 at 09:54
  • @JacobVlijm If all the problems I have pointed out with that approach cannot convince you, then the only thing that could possibly convince you is getting bitten by one of those problems yourself. I can assure there is no way you are going to convince me. Because I know the practice you suggest is more typing, and more error prone. – kasperd Apr 24 '16 at 12:24
  • @kasperd I do not have the intention to convince you :). Use whatever you like. Just need to mention to others that it is your choice. – Jacob Vlijm Apr 24 '16 at 12:28

4 Answers4

28

There's two things needed.

  1. A script must have #! line telling the OS which interpreter to use. In your case your very first line in the code must be #!/usr/bin/env python3
  2. You need to open file manager , go to Edit -> Preferences -> Behavior, and select what to do with executable files

    enter image description here

    1. Finally , make sure your file itself actually has executable permissions set. In terminal you can do chmod +x /path/to/script.py and in GUI, right click on the file and alter its Properties -> Permissions

    enter image description here

    enter image description here

Note about shebang line

The very first line is called shebang line and must start with #! ; whatever comes next is the name of the interpreter that will read your code. In case you are using python3 you could use either #!/usr/bin/python3 or #!/usr/bin/env python3 for portability. If you are not using code that will be specific to python version - just use #!/usr/bin/env python

Note on the script output:

If your script prints output to console, it will need to have terminal window, or alternatively use GUI dialogs such as zenity. Prefer using Run in Terminal option if you want to see the code. If you want the script to do something without seeing console output - use Run option.

enter image description here

In addition, if you have command line parameters , such as sys.argv[1] in the script , you can't set them unless you have terminal window open.

Sergiy Kolodyazhnyy
  • 105,154
  • 20
  • 279
  • 497
  • 1
    @PriyadarshiPaul That's the same as Files program on the launcher . In windows-speak that would be file explorer or My Computer – Sergiy Kolodyazhnyy Apr 23 '16 at 17:46
  • @PriyadarshiPaul it's nautilus in the Terminal – grooveplex Apr 23 '16 at 17:47
  • @grooveplex You probably meant that comment for Priyadarshi :) – Sergiy Kolodyazhnyy Apr 23 '16 at 17:48
  • @Serg I just can't get the meaning of this line " in GUI, right click on the file and alter its Properties -> Permissions" – Priyadarshi Paul Apr 23 '16 at 17:52
  • @Serg Now there is two options
    1. run
    2. run as terminal

    2nd option is working , but 1st is not . What to do?

    – Priyadarshi Paul Apr 23 '16 at 18:06
  • @PriyadarshiPaul 1st option is working. But it's doing so in background. You basically need to have terminal output or some form of gui dialog to see output. – Sergiy Kolodyazhnyy Apr 23 '16 at 18:15
  • 1
  • @Serg ok now for the run window stay in desktop , I have imported time module and using time.sleep(sec). But It is not working. – Priyadarshi Paul Apr 23 '16 at 18:26
  • @PriyadarshiPaul well , can you post the script source to paste.ubuntu.com and link it here ? Or better yet, create a new question on the site, because this particular question i'd say is solved. But please post it to paste.ubuntu.com first – Sergiy Kolodyazhnyy Apr 23 '16 at 18:40
  • 3
    #!/usr/bin/env python will invoke Python2 on most Ubuntu systems. Although you can make a Python script written for Python3 compatible with Python2, I would not assume that the OP has done so. #!/usr/bin/env python3 seems a more appropriate shebang – Anthon Apr 24 '16 at 09:22
  • I have to agree with @Anthon that the #! line should say python3 rather than just python. The OP explicitly mentioned python3 in the question. Simply specifying python without a version number means the script author has to ensure the script works all relevant versions, which today means python2 and python3, but in the future it may include python4 compatibility as well. – kasperd Apr 24 '16 at 10:20
  • @kasperd didn't i address that already at the ens of the answer ? – Sergiy Kolodyazhnyy Apr 24 '16 at 17:21
  • @Serg The paragraph near the end is fine. But the #! line shown at the top of your answer says just python. Since the question said python3, I think your first example should have said python3 as well. The problem is that specifying just python as interpreter name without a version number de facto means python2. And it is not easy to change that. Leaving out the version number while typing the script is one character less of typing. That's a very minor advantage, which does not outweigh the drawbacks of having to ensure your code works with both python2 and python3. – kasperd Apr 24 '16 at 17:33
  • @Serg And even if you are writing code which works with both python2 and python3, what advantages are there to leaving out the version number in the #! line rather than explicitly specifying one of the two versions? It's one character less typing, but that's not much of an advantage. I don't know of any other advantages from only typing python. If there are any, then please enlighten me. – kasperd Apr 24 '16 at 17:36
  • @kasperd There is one disadvantage: Arch Linux. python is python3. :/ – muru Apr 24 '16 at 17:50
  • 1
    And why are we bringing up Arch Linux here ? Maybe I'll come across as a bit mean , but we're talking Ubuntu here. On Ubuntu by default python is linked to python2.7 If you're developing software , you probably should be aware of what links where, if you use something other than your OS's default version, then explicitly specify so. Sure , we can cater to each individual question , but for crying out loud - if you code , then do it right . – Sergiy Kolodyazhnyy Apr 24 '16 at 17:55
  • @JonathanHartley That should not be the case. /usr/bin/python should always by Python 2. – Oli Apr 25 '16 at 09:12
  • You know what, yep I'm wrong. I upgraded from 15.10 to 16.04 and yes, just as you say, '/usr/bin/python' is still python2. I retract. – Jonathan Hartley Apr 25 '16 at 20:27
3

You need to put the location of the program to execute your code on the first line and you then need to set the script to run as an executable by changing its permissions. This assumes you're launching your applications from terminal or another script.

Find your Python installation

$ which python
/usr/bin/python

Add the programs location to the top line of your program with a #! in front

#!/usr/bin/python

# Python code goes here....

Set the Python script to have execution rights

$ chmod 700 test.py

Now you can run the script directly

$ ./test.py

Code listing for test.py

#!/usr/bin/python

print "test"
Joseph
  • 133
2

If you want to run this program without typing python3 mnik.py you have to make the script executable and make sure that python3 is used to run it.

The first you can do by running

 chmod +x mnik.py

the second you can do by adding as the first line of a script a shebang line that invokes python3. On all the Ubuntu systems I have worked with that came with python3, you can get python3 by adding this line at the top:

#!/usr/bin/env python3

After those two changes you can type /path/to/mnik.py, ./mnik.py or just mnik.py (the latter requires the script to be in your PATH).

If you make these changes you might also want to consider renaming mnik.py to mnik, that is common practice with Python packages with commands that are published on PyPI.

Anthon
  • 277
0

I have found a workaround if you don't want to bother with setting your script as an executable, adding comments to your code or selecting to run from the terminal every time you run it.

Go to ~/.local/share/applications, create a new .desktop file there. Call it something like python-run.desktop. Paste the following into it:

[Desktop Entry]
Name=Run Python Script
Comment=Python Interpreter
Exec=gnome-terminal -- /bin/bash -c 'python3 %f;echo "$(tput setaf 1)Program terminated.\nPress enter to exit...$(tput sgr 0)"; read'
Icon=/usr/share/pixmaps/python3.6.xpm
Terminal=true
Type=Application
Categories=Development;
StartupNotify=true
NoDisplay=true

This is mostly copied from the .desktop file of python interpreter itself. The difference is when you open it, it runs a new instance of the terminal line with the command: python3 %f;echo "$(tput setaf 1)Program terminated.\nPress enter to exit...$(tput sgr 0)"; read', which runs the script (%f is apparently the file's path), then pauses on exit.

Then go to nautilus, right click on the script, go to Properties → Open With and select Run Python Script, the "Application" we just created. Now when you double click, it should run the script from the terminal.

It's a pretty good workaround but I have found 2 problems with it:

  1. It doesn't work with scripts that have a space in their name.
  2. It opens a separate terminal window which is pretty annoying. For some reason, I couldn't get it to work by just setting Exec=python3 %f, it kept giving me an end of file exception whenever the program tried to get input. No idea why.
Eliah Kagan
  • 117,780
  • I think escaping the spaces in the filename would solve the first problem. And the second problem is because the stdin of your script is not connected to any tty (or pty(pseudo tty) in graphical terminals ).If you want to get the user input interactively in a non-graphical (text-based) way , opening a terminal or at least using the current one is necessary. – Parsa Mousavi Jun 15 '20 at 08:32