Post

Shebang Explained: What #!/usr/bin/env Does

Learn what the shebang line does in scripts and how to use it with zsh, bash, python, and swift.

Shebang Explained: What #!/usr/bin/env Does

The #!/usr/bin/env swift line at the top of a script file is called a shebang (or hashbang). It tells your system which interpreter should execute the code.

Anatomy of the Shebang

1
#!/usr/bin/env swift
PartPurpose
#!Signal to the kernel: “This is a script”
/usr/bin/envUtility that searches PATH for the program
swiftThe interpreter to use (swift, python, bash, zsh)

Why Use /usr/bin/env?

MethodExampleBehavior
Direct Path#!/usr/bin/swiftBreaks if Swift is installed elsewhere
Env Path#!/usr/bin/env swiftFinds Swift anywhere in PATH

Using env makes scripts portable. If someone installs Swift via Homebrew (/opt/homebrew/bin) or a version manager, the script still works.

Examples by Language

Bash Script

1
2
3
4
#!/usr/bin/env bash

echo "Running with Bash"
echo "Current shell: $BASH_VERSION"

Zsh Script

1
2
3
4
5
6
#!/usr/bin/env zsh

echo "Running with Zsh"
# Zsh arrays start at index 1
my_list=("Apple" "Banana")
echo "First item: $my_list[1]"

Python Script

1
2
3
4
5
#!/usr/bin/env python3

import sys
print(f"Python version: {sys.version}")
print("Hello from Python!")

Swift Script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/usr/bin/env swift

import Foundation

// Access command line arguments
let args = CommandLine.arguments

if args.count > 1 {
    print("Hello, \(args[1])!")
} else {
    print("Hello, World!")
}

// Use Foundation APIs
let currentDir = FileManager.default.currentDirectoryPath
print("Running in: \(currentDir)")

Running Scripts

Make the script executable, then run it directly.

1
2
chmod +x myscript.swift
./myscript.swift "iOS Developer"

Output:

1
2
> Hello, iOS Developer!
> Running in: /Users/mehmet/Dev

How It Works

When you execute ./myscript.swift:

  1. The kernel reads the first two bytes (#!)
  2. It identifies the file as a script, not a binary
  3. It reads the interpreter path from the shebang line
  4. It launches the interpreter and passes the script as input

The command ./myscript.swift becomes swift myscript.swift automatically.

Quick Reference

LanguageShebang
Bash#!/usr/bin/env bash
Zsh#!/usr/bin/env zsh
Python 3#!/usr/bin/env python3
Node.js#!/usr/bin/env node
Swift#!/usr/bin/env swift

For Swift scripts with external dependencies, consider using swift-sh which allows importing Swift packages directly in script files.

☕ Support My Work

If you found this post helpful and want to support more content like this, you can buy me a coffee!

Your support helps me continue creating useful articles and tips for fellow developers. Thank you! 🙏

This post is licensed under CC BY 4.0 by the author.