Bash Scripting
  • scripting list
  • How to Make Bash Script Executable Using Chmod
  • Shell Script to Check Linux Server Health
  • How to Concatenate String Variables in Bash [Join Strings]
  • How to Do Bash Variable Substitution (Parameter Substitution)
  • Bash Parameter Expansion with Cheat Sheet
  • Bash getopts with Examples
  • How to Pass all Arguments in Bash Scripting
  • Bash Function Return Value
  • Bash Loop Through Lines in a File
  • Bash readarray with Examples
  • Bash let with Examples
  • Bash expr with Examples
  • Bash read password
  • Bash for Loop Range Variable
  • Bash Arrays Explained
  • Ways to Find Bash Array Length
  • Bash Split String by Delimiter
  • Bash if Options
  • Bash If Statements for String Comparison
  • Debugging Techniques for Bash Scripts
  • Determining if a Bash String is Empty
  • Bash if Statement with Multiple Conditions
  • Meaning of Shebang in Bash Scripts
  • How to Comment Code in Bash Script
  • How to Read CSV File in Bash
  • Bash Scripting: How to Check if File Exists
  • Bash If Else Statements: Examples and Syntax
  • Bash Scripting: How to Check if Directory Exists
  • Bash eval Command with Examples
  • How to Use Sleep Command in Bash Scripting
  • Bash Associative Arrays with Examples
  • Bash Script for Counting Lines in a File
  • How to Use While Loop in Bash for Efficient Scripting
  • Bash basename Command with Examples
  • How to Create Multiline Strings in Bash
  • How to Use Bash if With && Operator
  • 50 Bash Script Examples to Kickstart Your Learning
  • Case statement in Bash Shell Scripting
  • Trimming White Space in Bash
  • How to Extract Filename from Absolute Path in Bash
  • How to Get Directory Path in Bash
  • Extract Extension from File Path in Bash
  • Extract Filename without Extension from Full Path in Bash
  • Bash for Each File in a Directory
  • Bash for Loop with Array
  • Bash Continue – Using with for Loop
  • Bash Backticks vs Dollar Parentheses $()
  • How to Assign Variable in Bash
  • How to Assign Variable in Bash
  • Bash Division Explained
  • Bash Modulo (Division Remainder)
  • Bash While Read Line by Line
  • Bash shift Command
  • Bash Looping Through Array of Strings
  • Bash read Command with Examples
  • Bash Check Empty Array
  • Using Bash For Loops to Iterate Over a List of Strings
  • Bash Break – Using with For Loop
  • How to Use seq With for Loop in Bash
  • How to Use $@ in Bash Scripting
  • Get the Current Script Directory in Bash
Powered by GitBook
On this page
  • What is Shebang?
  • What happens if we don’t have Shebang?
  • How does Shebang work?
  • Importance of Shebang
  • When can we ignore Shebang?
  • Conclusion

Meaning of Shebang in Bash Scripts

PreviousBash if Statement with Multiple ConditionsNextHow to Comment Code in Bash Script

Last updated 1 year ago

When writing shell scripts, the first line we often encounter is a hash (#), followed by an exclamation mark (!) with some path. The hash and the exclamation mark together is known as the shebang. This is an important aspect during the development and execution of the script.

What is Shebang?

Shebang is a sequence of characters that passes instructions and informs the kernel about the interpreter that should be used to run the commands present in our script file. To execute our script in a specific shell, provided that shell is supported by our system, we must begin are scripts with a #!. This was created because the users wanted to run the script which were not compiled, and hence, technically non-executables.

Example:

#!/bin/bash

This indicates that the interpreter must be a Bash shell.

What happens if we don’t have Shebang?

We have plenty of shells available for Linux systems which differ slightly in their syntaxes and interpretation. However, they mostly have a similar syntax. Let us take an example and write a script without a shebang.

Example:

echo "Good day"

We will open a terminal, give this script execute permissions and run it with the "." operator.

As we can see, the script is working without any shebang. This means this script uses the default shell to execute. We can check our default shell using the command:

echo $0.

Now we will take another example and write a script to check if the input is a number or not. Let’s save the below script named "isNumeric" and give it executable permissions.

Example

#!/bin/bashnumericCheck(){ if ! [[ "$1" =~ ^[0-9]+(\.[0-9]+)?$ ]] then echo $1 is non numeric. fi}numericCheck 5numericCheck A

Now we run the script as follows:

./isNumeric

The script is working as expected. Let us change the first line of the same script to #!/bin/ksh and rerun it.

We can notice that when there is a syntax error with an unexpected operator/operand '=~' as the KSH (Korn SHell) interpreter doesn’t recognize that. Hence, it is always suggested to mention the correct interpreter in the script. If not, some scripts may end up giving unexpected results when executed in different shells.

How does Shebang work?

Shebang is simply the absolute path to the Bash interpreter. Almost every bash script will have #!/bin/bash as their first line. This ensures that Bash will be employed for the interpretation of the script, even if it is executed under a different shell.

When we run an executable file, the "execve" program gets called to replace the current process with a new one. Say we try to run a text file, the execve program will look for the first two characters to be present in the file to be "#!" followed by the absolute path of the interpreter.

If the text file has had its executable bit set, and the Shebang is followed by a valid command interpreter, Linux passes the script to the interpreter which will be reading the rest of the script and processing it accordingly.We can see the working of the shebang as using the trace command as follows:

strace bash -c './scriptname' 

Syntax

#!/path/to/interpreter [arguments]

Bash shebang options

Let’s assume we have a script script1, beginning with #!/bin/bash and we run the script as follows:

script1 arg1 arg2 

This is equivalent to executing

/bin/bash script1 arg1 arg2. 

Similarly, if we have specified the shebang line with arguments say, #!/bin/bash -ex, this is equivalent to executing

/bin/bash -ex script1 arg1 arg2.

Here, we have made use of the commonly used arguments e and x. This is just adding shell options to the shebang:

  • -e tells us that if there is any command that is returning a non-zero status, the script will terminate immediately. This appears a good idea, but it acts inconsistently and has very complex rules to abort.

  • -x makes the shell display the execution trace. It prints the commands and their arguments as they get called for execution.

  • -v displays the shell input lines as it reads the file.

It is not a good practice to set the shell options in the shebang as they will not be playing any role if the script is invoked directly with the command:

bash <scriptName> 

Types of Shebang

#!/bin/bash - It is the common shebang line present in every script. It informs the kernel to use the Bash interpreter present in the /bin directory. If no shebang line is provided, this is the default one.

#!/usr/bin/env bash - The shell might be present in different locations in different Linux distros. As we are using Ubuntu, we can see, in our examples, that bash is present in the /usr/bin/ directory. Some users also tend to customize their shells in different locations. The "env" command enables us to run our piece of code in any environment. It tries to find bash in the environment variable PATH. The moment there is a match, it stops the search and runs with that match. Here is an example of how we can use it:

Some commonly used interpreters are:

  • #!/bin/sh - We can execute the file using the Bourne or any compatible shell with the help of this interpreter.

  • #!/bin/bash - The presence of this Shebang line enables us to execute the file using the Bash shell.

  • #!/usr/bin/pwsh - This ensures that our script executes the file using PowerShell.

  • #!/usr/bin/env python3 - We look for the python interpreter in the path variable and then execute our script with it.

  • #!/usr/bin/python3 - This ensures our files execute as python scripts.

  • #!/bin/false - We get a non-zero exit status,indicating failure, when employing this interpreter.

  • #!/bin/perl - It executes our files as if they are perl scripts.

  • #!/usr/bin/env perl - It executes our files as perl scripts using the env.

We can either specify the full path of the interpreter or use the env command in our shebang line. Shebang lines may include specific options that are passed to the interpreter. However, implementations vary in the parsing behavior of the options.

Importance of Shebang

Since there are lots of shells available, we have seen what happens if we do not specify the shebang. Shebang makes shell scripts behave like actual executable files.It allows the other available interpreters to fit in seamlessly.

As a result, we don't need to mention anything. We just need to use the dot (.) operator with the filename and run it on the terminal. The shebang mentioned on the first line will be picked and it will make the script file executable

When can we ignore Shebang?

If we do not specify an interpreter line, the default is usually the /bin/sh. But, it is always recommended that we set #!/bin/bash line for our scripts. Shebang can be overlooked if we explicitly specify the shell. Overriding the Shebang is also possible at the command line.

Say, our script has the Shebang #!/bin/ksh. We can override to run as bash.

Example:

bash <script-name>

As we have seen earlier, we should avoid the override of the shebang line. This ensures we get a highly consistent output.

Conclusion

  • Shebang should be our first line in the script.

  • Shebang has the absolute path of the interpreter.

  • It determines how a script executes.

  • We can override the shebang line but it is not a good practice.

change to #!/bin/ksh
check default shell
without shebang
avoid the override of the shebang line
run the script with Shebang #!/bin/bash