Why Do You Need to Put #!/Bin/Bash At the Beginning of a Script File

Why do you need to put #!/bin/bash at the beginning of a script file?

It's a convention so the *nix shell knows what kind of interpreter to run.

For example, older flavors of ATT defaulted to sh (the Bourne shell), while older versions of BSD defaulted to csh (the C shell).

Even today (where most systems run bash, the "Bourne Again Shell"), scripts can be in bash, python, perl, ruby, PHP, etc, etc. For example, you might see #!/bin/perl or #!/bin/perl5.

PS:
The exclamation mark (!) is affectionately called "bang". The shell comment symbol (#) is sometimes called "hash".

PPS:
Remember - under *nix, associating a suffix with a file type is merely a convention, not a "rule". An executable can be a binary program, any one of a million script types and other things as well. Hence the need for #!/bin/bash.

Bash Script : what does #!/bin/bash mean?

That is called a shebang, it tells the shell what program to interpret the script with, when executed.

In your example, the script is to be interpreted and run by the bash shell.

Some other example shebangs are:

(From Wikipedia)

#!/bin/sh — Execute the file using sh, the Bourne shell, or a compatible shell
#!/bin/csh — Execute the file using csh, the C shell, or a compatible shell
#!/usr/bin/perl -T — Execute using Perl with the option for taint checks
#!/usr/bin/php — Execute the file using the PHP command line interpreter
#!/usr/bin/python -O — Execute using Python with optimizations to code
#!/usr/bin/ruby — Execute using Ruby

and a few additional ones I can think off the top of my head, such as:

#!/bin/ksh
#!/bin/awk
#!/bin/expect

In a script with the bash shebang, for example, you would write your code with bash syntax; whereas in a script with expect shebang, you would code it in expect syntax, and so on.

Response to updated portion:

It depends on what /bin/sh actually points to on your system. Often it is just a symlink to /bin/bash. Sometimes portable scripts are written with #!/bin/sh just to signify that it's a shell script, but it uses whichever shell is referred to by /bin/sh on that particular system (maybe it points to /bin/bash, /bin/ksh or /bin/zsh)

What does the line #!/bin/sh mean in a UNIX shell script?

It's called a shebang, and tells the parent shell which interpreter should be used to execute the script.

#!/bin/sh <--------- bourne shell compatible script
#!/usr/bin/perl <-- perl script
#!/usr/bin/php <--- php script
#!/bin/false <------ do-nothing script, because false returns immediately anyways.

Most scripting languages tend to interpret a line starting with # as comment and will ignore the following !/usr/bin/whatever portion, which might otherwise cause a syntax error in the interpreted language.

Why we use #!/bin/bash in Bash script?

This line is called shebang. It’s a ‚magic‘ line telling the program loader (kernel) how to execute a script on unixoid systems.

Cf. https://en.m.wikipedia.org/wiki/Shebang_(Unix)

What is the difference between #!/usr/bin/env bash and #!/usr/bin/bash?

Running a command through /usr/bin/env has the benefit of looking for whatever the default version of the program is in your current environment.

This way, you don't have to look for it in a specific place on the system, as those paths may be in different locations on different systems. As long as it's in your path, it will find it.

One downside is that you will be unable to pass more than one argument (e.g. you will be unable to write /usr/bin/env awk -f) if you wish to support Linux, as POSIX is vague on how the line is to be interpreted, and Linux interprets everything after the first space to denote a single argument. You can use /usr/bin/env -S on some versions of env to get around this, but then the script will become even less portable and break on fairly recent systems (e.g. even Ubuntu 16.04 if not later).

Another downside is that since you aren't calling an explicit executable, it's got the potential for mistakes, and on multiuser systems security problems (if someone managed to get their executable called bash in your path, for example).

#!/usr/bin/env bash #lends you some flexibility on different systems
#!/usr/bin/bash #gives you explicit control on a given system of what executable is called

In some situations, the first may be preferred (like running python scripts with multiple versions of python, without having to rework the executable line). But in situations where security is the focus, the latter would be preferred, as it limits code injection possibilities.

shell-script headers (#!/bin/sh vs #!/bin/csh)

This is known as a Shebang:

http://en.wikipedia.org/wiki/Shebang_(Unix)

#!interpreter [optional-arg]

A shebang is only relevant when a script has the execute permission (e.g. chmod u+x script.sh).

When a shell executes the script it will use the specified interpreter.

Example:

#!/bin/bash
# file: foo.sh
echo 1

$ chmod u+x foo.sh
$ ./foo.sh
1

source script does not honor #!/bin/bash -ex and exit when a command fails

The shebang line is used to let a script tell the operating system what interpreter to run it with.

When you use source, you're telling your current shell interpreter to evaluate the script's commands internally.

Thus, the operating system doesn't need to start a new interpreter for the script.

Thus, the operating system never invokes the shebang line.

Thus, arguments such as -ex on that line are never invoked when your script is run with source.


Solutions are twofold:

  • Use set -e as a separate line if you really do want to have this effect (but see BashFAQ #105 for reasons why you shouldn't).
  • Don't use source except when you have a very explicit reason to run a script within your existing interpreter (and change that interpreter's state). And when you do have such a reason, running set -e is almost certainly a thing you don't want to do.


Related Topics



Leave a reply



Submit