linux - What does the file extension do if I can execute a python file without it?

07
2014-07
  • Zen

    I'm using Ubuntu 14.04. And I have an astonish finding today: I can execute a python file without a file extension!

    e.g.

    $ echo " print 'hello' " > z
    $ python z
    hello
    

    So, why do we need a file extension? Does it has authentic influence to the file other than tell people semantically what file this is?

  • Answers
  • mtak

    If you are talking about the extension, Linux does not use extensions the same way Windows does, in fact, extensions have no meaning at all in Linux and are just part of the filename. They are still being used a lot to make it easier for people to recognize files. One common occurrence where extensions are not being used is with binary executables (you can use python instead of python.exe).

    There are two ways of running scripts:

    • Invoking from shell (./scriptname.py): In the script, the first line will say something along the lines of #!/usr/bin/python. The #! instructs the kernel to use the subsequent file as interpreter for the script.

      From http://en.wikipedia.org/wiki/Shebang_%28Unix%29

      The shebang is actually a human-readable instance of a magic number in the executable file, the magic byte string being 0x23 0x21, the two-character encoding in ASCII of #!. This magic number is detected by the "exec" family of functions, which determine whether an image file is a script or an executable binary. The presence of the shebang will result in the execution of the specified executable, usually an interpreter for the script's language.

    • Invoking the interpreter with script as argument (python scriptname). If you do this, you start the interpreter, and you tell it explicitly what script to run. The script can be any file, with any 'extension'.


  • Related Question

    linux - How do *.pyc files execute?
  • Questioner

    I noticed importing an executable Python file saves a *.py[co] file, as expected, but that file also is marked executable. Randomly, I wondered if I could execute this file directly, and it worked!

    Steps to duplicate:

    $ echo 'print "Worked."' > testcase.py
    $ chmod u+x testcase.py
    $ python -c 'import testcase'
    Worked.
    $ ./testcase.pyc
    Worked.
    

    How did this work? Why didn't I get an error message? Is my system, Ubuntu 9.04, doing something special, or am I forgetting something on how Linux works in general?

    $ python --version
    Python 2.6.2
    $ hd testcase.pyc
    00000000  d1 f2 0d 0a a4 4f 08 4b  63 00 00 00 00 00 00 00  |.....O.Kc.......|
    00000010  00 01 00 00 00 40 00 00  00 73 09 00 00 00 64 00  |[email protected].|
    00000020  00 47 48 64 01 00 53 28  02 00 00 00 73 07 00 00  |.GHd..S(....s...|
    00000030  00 57 6f 72 6b 65 64 2e  4e 28 00 00 00 00 28 00  |.Worked.N(....(.|
    00000040  00 00 00 28 00 00 00 00  28 00 00 00 00 73 0b 00  |...(....(....s..|
    00000050  00 00 74 65 73 74 63 61  73 65 2e 70 79 74 08 00  |..testcase.pyt..|
    00000060  00 00 3c 6d 6f 64 75 6c  65 3e 01 00 00 00 73 00  |..<module>....s.|
    00000070  00 00 00                                          |...|
    00000073
    

    (Including hexdump to show there's no shebang line, and reading about .pyc format, there's nothing here that isn't highly specific to Python.)


  • Related Answers
  • Chris Johnsen

    Perhaps your system has a binfmt_misc entry for .pyc files. Look in /proc/sys/fs/binfmt_misc for the entry.

  • momeara

    .pyc files are byte compiled versions of the original .py file. When a .py file is executed by python, it first checks to see if there is a .pyc file with the same name and that the original .py file hasn't been modified since the .pyc file was created. It both of these are true then it executes the .pyc file because it can save the step of byte compiling the .py file thus making the execution time faster. So the .pyc file really is executable just like you discovered.

  • Pridkett

    Just because a file is marked executable does not mean that the OS knows how to execute it. What happened here is that the .pyc file inherited some of the permissions (or assumed default filesystem permissions, for example, if you're on a FAT32 drive in Linux).

    In general, you don't execute .pyc files. Python stores them so it doesn't have to recompile the code every time it is imported.