You’ve probably seen shell scripts starting with
#!/bin/sh. For a long time, I noticed that some scripts ran fine without it, while others failed. It wasn’t until I started developing Alfred Workflows that I realized this line has a specific name and purpose: it’s called a Shebang.

What is a Shebang?
- The Syntax: A Shebang consists of the characters
#!. For it to work, these must be the very first two characters on the first line of the file. - The Mechanism: When a Unix-like operating system (like macOS or Linux) encounters a file with a Shebang, the program loader parses the rest of the line as an interpreter directive. It then executes that interpreter and passes the script’s file path as an argument.
- Execution vs. Interpretation: Without a Shebang, a script cannot be executed directly (e.g.,
./script.sh). However, it can still be run if you manually pass it to an interpreter (e.g.,bash script.sh).
Common Examples
#!/bin/sh: Executes the script usingsh(Bourne shell or a compatible replacement).#!/bin/bash: Specifically uses thebashshell, which often contains features not found in standardsh.#!/usr/bin/env node: Executes the script using Node.js. By using/usr/bin/env, the system looks fornodein the user’s current$PATH, which is more portable than hardcoding an absolute path like/usr/local/bin/node.
Node.js Script Example
Consider this simple Node.js script:
#!/usr/bin/env node
console.log(
JSON.stringify({
response: "Hello from Node!",
environment: process.env.USER
})
);
If you save this as test.js and give it execution permissions (chmod +x test.js), you can run it directly in your terminal with ./test.js. If you were to remove the first line, the system wouldn’t know which program to use to run the code, and the execution would fail unless you typed node test.js.
Final Thoughts
Using a Shebang is a best practice for writing portable scripts. It ensures that your scripts run correctly regardless of how they are invoked or which default shell the user is running.

