It is said that in linux, unlike Windows, there's not a clear border between executables and other files.Well, in Windows, I write a C++ program, then it is precompiled, compiled and then linked to become a distinguished file: executable. The changes are so much that they are not reversible.But in Linux a simple text file containing a code is executed. So what do compilation and linkage do? If a code is executed, why is it compiled? What's good in this process and what is the main difference between the code and the final (so called) executable file in Linux? Why portability of programs is limited in Linux and needs a lot of (version specific) dependency requirements, if they are codes?
On executable files in Linux
shell script;files;linux kernel;executable;binary
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:BinariesScriptsThe first type works exactly as .exes 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 .exes. 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/bashWhen 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_scriptIn 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.