Shebang, Hebang, and Webang lines. Execute any type of file from the  terminal - DEV Community

Probably you have seen many scripts starting with “!#/usr/bin/env”.
You might be curious to know what is that “#!” and what it does.

The operating system is responsible for loading user programs coming in different formats.

The most popular binary format in the Linux world is ELF which is the format of most programs you see in your system.

The other popular format is the script.

The Linux detects the format of files by reading a few bytes of the file. Files begin with the identifier of their format called Magic number.

Here is the list of some popular file formats:

HEX               ISO 8859–1     Description
25 50 44 46 2D    %PDF-          PDF Document
7F 45 4C 46       ␡ELF           Executable and Linkable Format
23 21             #!             Script

Example: check the Magic number of “ls” command

hexdump -c $(which ls) | head -n1
0000000 177 E L F 002 001 001 \0 \0 \0 \0 \0 \0 \0 \0 \0

The OS knows how to treat each file format.

Let’s see how OS treats with script format.

The script binary format is implemented in fs/binfmt_script.c

Let’s go through the source code to see how it works.

# fs/binfmt_script.c:145
 
static int __init init_script_binfmt(void)
{
 register_binfmt(&script_format);
 return 0;
}

It registers a new binary format by referencing to variable script_format

# fs/binfmt_script.c:140static struct linux_binfmt script_format = {                                 .module  = THIS_MODULE,
.load_binary = load_script,                             
};

It creates the variable script_format which is kind of a struct named linux_binfmt . All binary formats in Linux is presented by that struct.
`load_script` is the function loads script formats.

Let’s see how load_script is implemented.

# fs/binfmt_script.c:34static int load_script(struct linux_binprm *bprm)                             {                             
const char *i_name, *i_sep, *i_arg, *i_end, *buf_end;                        struct file *file;
int retval;                                                            /* Not ours to exec if we don't start with "#!". */                              if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!'))                               return -ENOEXEC;

It checks the Magic number. If it is not starting with “#!”, this module can not load it, it means other module will be responsible to load that format.

# fs/binfmt_script.c:132file = open_exec(i_name);
if (IS_ERR(file))
   return PTR_ERR(file);bprm->interpreter = file;

It runs the program passed after “#!” and sets it as interpreter of current file.

[“source=medium”]