The Unix Legacy

To fully understand the launcher’s protocols, we have to begin with a short history lesson. Unix developers long ago devised a protocol for designating a program to run a script’s code. On Unix systems (including Linux and Mac OS X), the first line in a script’s text file is special if it begins with a two-character sequence: #!, sometimes called a shebang (an arguably silly phrase I promise not to repeat from here on).

Chapter 3 gives a brief overview of this topic, but here’s another look. In Unix scripts, such lines designate a program to run the rest of the script’s contents, by coding it after the #!—using either the directory path to the desired program itself, or an invocation of the env Unix utility that looks up the target per your PATH setting, the customizable system environment variable that lists directories to be searched for executables:

#!/usr/local/bin/python
...script's code              # Run under this specific program

#!/usr/bin/env python
...script's code              # Run under "python" found on PATH

By making such a script executable (e.g., via chmod +x script.py), you can run it by giving just its filename in a command line; the #! line at the top then directs the Unix shell to a program that will run the rest of the file’s code. Depending on the platform’s install structure, the python that these #! lines name might be a real executable, or a symbolic link to a version-specific executable located elsewhere. These lines might also name a more specific executable explicitly, such as python3. Either way, by changing #! lines, symbolic links, or PATH settings, Unix developers can route a script to the appropriate installed Python.

None of this applies to Windows itself, of course, where #! lines have no inherent meaning. Python itself has historically ignored such lines as comments if present on Windows (“#” starts a comment in the language). Still, the idea of selecting Python executables on a per-file basis is a compelling feature in a world where Python 2.X and 3.X often coexist on the same machine. Given that many programmers coded #! lines for portability to Unix anyhow, the idea seemed ripe for emulating.