Shebang Explained: #! in Bash and Shell Scripts

When you run a script as an executable file, the operating system needs to know which program should read it. That instruction is usually written on the first line of the file as a shebang, which starts with #! followed by an interpreter path.
A shebang can point to Bash, a POSIX shell, Python, Perl, Node.js, AWK, or another interpreter. This guide explains how shebang lines work in general, then shows how to choose the right Bash shebang for shell scripts.
What Is a Shebang?
A shebang is the interpreter directive at the top of an executable script. It tells the kernel which program to use when you run the file directly, such as ./script.sh.
For example, this shebang tells the system to run the script with Bash:
#!/bin/bashThe #! characters are sometimes called hashbang, sharp-bang, or pound-bang. In day-to-day shell scripting, shebang is the most common name.
If the script is not executable and you run it by passing it to an interpreter, the shebang is not used:
bash script.shIn that case, bash is already the interpreter.
Shebang Syntax
The shebang line takes the following form:
#!interpreter [arguments]- The shebang must be the first line in the script.
- It must start with
#!. - Whitespace after
#!is optional, but most scripts omit it. - The interpreter is usually an absolute path, such as
/bin/shor/bin/bash. - Interpreter arguments are optional.
Common examples include:
#!/bin/bash- Usesbashto parse the file.#!/usr/bin/env perl- Uses theenvcommand to find the path to theperlexecutable.#!/usr/bin/env python3- Executes the file using thepython3binary.
Common Shebang Lines
| Shebang | Interpreter |
|---|---|
#!/bin/sh | POSIX shell |
#!/bin/bash | Bash using an absolute path |
#!/usr/bin/env bash | Bash found through $PATH |
#!/usr/bin/env python3 | Python 3 |
#!/usr/bin/env node | Node.js |
#!/usr/bin/env perl | Perl |
#!/usr/bin/env ruby | Ruby |
#!/usr/bin/awk -f | AWK |
Use the shebang that matches the language and syntax used in the file. A script that uses Bash arrays, [[ ]], or brace expansion should not use #!/bin/sh.
Bash Shebang: /bin/bash vs /usr/bin/env bash
If a shebang is not specified and you run the script with ./script.sh, the kernel’s execve() call fails to find an interpreter and the calling shell attempts to run it as a shell script. In practice, this means the script is interpreted by /bin/sh, which may not support Bash-specific features. To ensure that your script is always interpreted with Bash, you need to specify the executable path using a shebang.
There are two ways to set the interpreter:
Using the absolute path to the bash binary:
sh#!/bin/bashUsing the
envutility:sh#!/usr/bin/env bash
The advantage of the second approach is that it searches for the bash executable in the user’s $PATH
environment variable. If there is more than one path to bash, the first one found will be used. This makes scripts more portable across systems where Bash may not be installed at /bin/bash (such as FreeBSD or NixOS).
Passing Options to the Interpreter
When using the absolute path, you can pass options directly to the interpreter. For example, to run the script in debug mode:
#!/bin/bash -xWhen using env, you cannot pass options on the shebang line in the traditional way. Instead, use set inside the script:
#!/usr/bin/env bash
set -xOn systems with coreutils 8.30+ (2018), you can use env -S to split arguments:
#!/usr/bin/env -S bash -x#!/bin/sh vs #!/bin/bash
These two shebangs are not interchangeable:
#!/bin/shinvokes the system’s POSIX-compliant shell. On Debian and Ubuntu, this is typicallydash, a lightweight shell that lacks many Bash features.#!/bin/bashinvokes Bash specifically, giving you access to arrays,[[ ]]tests,{1..10}brace expansion, and other Bash-only features.
Use #!/bin/sh when your script only uses POSIX syntax and you want maximum portability. Use #!/bin/bash when your script relies on Bash-specific features.
Example Script
Create a simple script that uses a shebang and prints “Hello, World”. Open your text editor
and create a file called hello_world:
nano hello_world#!/bin/bash
echo "Hello, World"To be able to run the script without specifying the interpreter from the command line, you need to make the file executable :
chmod +x hello_worldNow you can run the script by typing ./ followed by the script name:
./hello_worldHello, WorldOverriding the Shebang
If for some reason you want to override the interpreter set in the shebang line, run the script by explicitly specifying the desired shell.
For example, to run a script that has #!/bin/sh specified in the shebang line using the bash shell, you would type:
bash hello_worldNote that overriding the shell interpreter is not recommended, as it may lead to unexpected behavior.
Troubleshooting
bad interpreter: No such file or directory
The interpreter path in the shebang does not exist, or the file uses Windows CRLF line endings. Check the first line with head -n 1 script.sh, then verify the interpreter with command -v bash or ls -l /bin/bash.
/bin/bash^M: bad interpreter
The script was saved with Windows line endings, so Linux reads the carriage return as part of the interpreter path. Convert the file to Unix line endings with dos2unix script.sh or sed -i 's/\r$//' script.sh.
The script uses the wrong Bash path
Some systems use /bin/bash, while others may have Bash in another location. Check the path with command -v bash. If you need a more portable Bash shebang, use #!/usr/bin/env bash.
Bash syntax fails when the script runs with sh
If the script uses Bash-only syntax such as arrays, [[ ]], or brace expansion, use #!/bin/bash or #!/usr/bin/env bash. Running the same file with sh script.sh overrides the shebang and may fail.
Permission denied when running ./script.sh
The file is not executable. Add execute permission with chmod +x script.sh, then run it again with ./script.sh.
Quick Reference
| Task | Command / Syntax |
|---|---|
| Shebang syntax | #!interpreter [arguments] |
| Bash shebang (absolute) | #!/bin/bash |
| Bash shebang (portable) | #!/usr/bin/env bash |
| POSIX shell shebang | #!/bin/sh |
| Python 3 shebang | #!/usr/bin/env python3 |
| Pass options (absolute) | #!/bin/bash -x |
| Pass options (env) | #!/usr/bin/env -S bash -x |
| Make script executable | chmod +x script.sh |
| Run script | ./script.sh |
| Override interpreter | bash script.sh |
| Find Bash path | command -v bash |
FAQ
What does a shebang mean?
A shebang tells the operating system which interpreter should run an executable script. It starts with #! and is followed by the interpreter path.
What does #!/bin/bash mean?
It tells the operating system to use the Bash interpreter at /bin/bash to execute the script.
Should I use #!/bin/bash or #!/usr/bin/env bash?
Use #!/usr/bin/env bash for portability. It searches $PATH for Bash, which works across systems where Bash is not at /bin/bash. Use the absolute path when you need to pass interpreter options directly on the shebang line.
What happens if I omit the shebang?
The kernel cannot determine the interpreter, so the calling shell attempts to run the script itself. This typically results in the script being interpreted by /bin/sh, which may not support Bash-specific syntax.
Can I use a shebang with Python or other languages?
Yes. Use #!/usr/bin/env python3 for Python, #!/usr/bin/env node for Node.js, #!/usr/bin/env perl for Perl, and so on.
Conclusion
The shebang (#!) tells the operating system which interpreter to use when executing a script. Use #!/bin/bash or #!/usr/bin/env bash for Bash scripts, and choose a different interpreter when the script is written for another language. To learn all the ways to execute scripts, see our guide on how to run a Bash script
.
Tags
Linuxize Weekly Newsletter
A quick weekly roundup of new tutorials, news, and tips.
About the authors

Dejan Panovski
Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 800+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.
View author page