tl;dr: the difference is the executable bit.
The answer lies in the UNIX permissions model. To be honest, I forget what the Windows permissions model is, but in UNIX (and hence GNU/Linux), there are three main permission bits that can be set on a file: read, write, and execute. These bits can be set on anything. There are two main types of files that you would want to set the executable bit on:
- Binaries
- Scripts
The first type works exactly as .exe
s do in Windows. The only difference is that the ability of the file to be executed is determined by a permission bit in the filesystem, instead of the file extension. Binaries do still have a format, just like .exe
s. On GNU/Linux, this format is called ELF. The Linux kernel has special logic that tells it how to read the format of ELF binaries. When you execute a binary, it is this logic that actually runs the code.
The part that is confusing you is the second type of executable: scripts. Scripts are regular text files that can be executed by an interpreter, like python
or bash
. Scripts start with something called a shebang, which looks like this: #!
. When a script is "executed", the kernel recognizes the shebang and executes whatever binary is specified after it, with the path of the script you are executing as an argument.
For example, let's say I have a script with the executable bit set, at the path /home/alex/bin/test_script
. This script has the following as the first line:
#!/bin/bash
When you execute this script, the kernel will recognize the shebang at the beginning. It will then load /bin/bash
and pass it /home/alex/bin/test_script
as the first argument. This would be the equivalent of executing the following on the command line:
/bin/bash /home/alex/bin/test_script
In this way, bash
is loaded to interpret, or "execute", the script.
As a small aside, the change from source to binary is not so great that it cannot be reversed. Retrieving source code from a binary is called decompiling.
.bat
(batch) files, for example. These work pretty similarly to shell scripts. Windows figures out how to handle a file based on its extension; Unix based on its permissions (execute bits) & content.