shebang
Summary #
- tags
- ,
The #! - shebang- is used to tell the kernel which interpreter, execution environment, 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. For didactic purposes, let’s consider it saves in a variable called command the string starting after the shebang and ending in the end of line.
After this the kernel tries to run a command with the contents of the command and giving as the first argument the filename of the file we’re trying to execute.
hello.sh
#!/bin/bash
echo "Hello World!"
Assuming this file has the executable permission, when you type this in the command line:
$ ./hello.sh
# is equal to
/bin/bash hello.sh
Why some people use #!/usr/bin/env?
#
- You probably saw some scripts starting with
#!/usr/bin/envbash where you’re used to see just#!/bin/bash. - The reason of this is to increase the portability of the script (even thought it’s a debatable matter, as we’re going to see below).
- The
envcommand, if used with no arguments, prints a (big) list with all the environment’s variables. - But if
envis used followed by a command, it runs that command in another instance of the shell./usr/bin/env # using with argument /usr/bin/env bash
Portability #
When you use #!/bin/bash you’re clearly saying that bash is in the bin directory. This seems to be the default in all Linux distributions, but there are other Unix flavors where it can possibly not happen (for example the bash can be placed in the usr/bin). In systems like that your script starting with #!/bin/bash would cause a bad interpreter: No such file or directory.
When you run env bash, the env will search for bash in your $PATH variable, and then run the first one it finds. Usually bash is in bin, but a user running your script on some other system can have it in /usr/bin/ or even testing an alternative version in /home/user/bin/bash.