I have a simple perl script as below:
#!/usr/bin/perl use strict; use warnings; print "hello world!\n";
I can execute this script as below:
>temp.pl hello world! >
If I add some comments like this:
#this script is just for test #the shebang #!/usr/bin/perl use strict; use warnings; print "hello world!\n";
and when I try to execute, it gives me output as below:
> temp.pl use: Command not found. use: Command not found. print: Command not found. >
The point here is the shebang line should be always at the top, no matter what. Can anybody explain why?
Adding #!/bin/bash as the first line of your script, tells the OS to invoke the specified shell to execute the commands that follow in the script. #! is often referred to as a "hash-bang", "she-bang" or "sha-bang".
shebang is used to tell the kernel which interpreter should be used to run the commands present in the file. When we run a file starting with #! , the kernel opens the file and takes the contents written right after the #! until the end of the line.
The shebang character sequence is always used in the first line of any file. The statement that mentions the program's path is made by using the shebang character first and then the path of the interpreter program.
The name shebang for the distinctive two characters may have come from an inexact contraction of SHArp bang or haSH bang, referring to the two typical Unix names for them. Another theory on the sh in shebang is that it is from the default shell sh, usually invoked with shebang.
The shebang must be the first line because it is interpreted by the kernel, which looks at the two bytes at the start of an executable file. If these are #!
the rest of the line is interpreted as the executable to run and with the script file available to that program. (Details vary slightly, but that is the picture).
Since the kernel will only look at the first two characters and has no notion of further lines, you must place the hash bang in line 1.
Now what happens if the kernel can't execute a file beginning with #!whatever
? The shell, attempting to fork an executable and being informed by the kernel that it can't execute the program, as a last resort attempts to interpret the file contents as a shell script. Since the shell is not perl, you get a bunch of errors, exactly the same as if you attempted to run
sh temp.pl
It's not just that it has to be the first line, the characters #!
have to be the first two bytes in the file. That this can run scripts is a shell feature, not an OS one, and it's not specific to any particular scripting language.
When the system is told to execute the contents of a file, either with something like .../path/to/bin/program
, or via the analogous route through the PATH, it examines the first few bytes of the file to look for the 'magic numbers' which reveal what type of file it is (you can peek at that process using the file(1) command). If it's a compiled binary, then it'll load and execute it in an appropriate manner, and if those first two bytes are #!
it'll do the 'shebang-hack'.
The 'shebang-hack' is a special case that's employed by some shells (in fact, essentially every one, but it's convention rather than a requirement), in which the shell reads the remaining bytes up to a newline, interprets these as a filename, and then executes that file giving it the rest of the current file as input. Plus some details you can probably read about elsewhere.
Some (versions of) shells will allow quite long first lines, some allow only short ones; some allow multiple arguments, some allow only one.
If the file doesn't start with #!
, but does appear to be text, some shells will heuristically try to execute it anyway. Csh (if I recall correctly) takes a punt on it being a csh-script, and there's some complicated and arcane case to do with some shells' behaviour if the first line is blank, which life is too short to remember.
There are interesting and extensive details (and accurate ones, in the sense that they match my recollections!) at Sven Mascheck's #! page.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With