1. 什么是 Shebang 行

有些python文件第一行为:

#!/usr/bin/env python3

这一行特殊注释就是Shebang 行。用于告诉操作系统用哪个解释器来执行这个文件。

“Shebang”名称来源于前两个字符 #! 的读音组合:

#  →  sharp(sharp 号)或 hash
!  →  bang(感叹号的俚语)

hash + bang = hashbang → shebang

也有说法来自 shell + bang,因为最初用于 shell 脚本。

2. Shebang 行的工作原理

2.1 Shebang原理介绍

Shebang 行的本质:让 Linux/macOS 把 .py 文件当作可直接执行的命令,而不是需要手动指定解释器的文本文件。如果你的脚本只是被 python3 命令调用或被其他模块导入,shebang 就没有意义。

┌─────────────────────────────────────────────────────┐
│  当你执行:  ./script.py                              │
│                                                     │
│  操作系统读取文件头部的 #! 标记                         │
│       ↓                                             │
│  找到解释器路径:/usr/bin/env python3                  │
│       ↓                                              │
│  实际执行:/usr/bin/env python3 ./script.py           │
└─────────────────────────────────────────────────────┘

“/usr/bin/env python3”  vs  “/usr/bin/python3”

#!/usr/bin/python3        # ❌ 硬编码路径,不同系统路径可能不同
#!/usr/bin/env python3    # ✅ 通过 env 在 PATH 中查找 python3,更通用

实际演示:

# 创建脚本
cat > hello.py << 'EOF'
#!/usr/bin/env python3
print("Hello, World!")
EOF

# 添加执行权限
chmod +x hello.py

# 有 shebang 时,直接执行(不需要写 python3 hello.py)
./hello.py          # ✅ 正常运行

# 对比:没有 shebang 时
./no_shebang_hello.py    # ❌ 报错:权限拒绝 或 无法识别格式
python3 no_shebang_hello.py   # ✅ 显式指定解释器,不依赖 shebang

2.2 为什么用 ./script.py 而不是 script.py

加上shebang行后,执行脚本时用“./script.py” 而不是 “script.py”。这与 Linux/macOS Shell 命令查找机制有关,与 shebang 无直接关系。

Shell 如何查找命令?

当你在终端输入一个命令,Shell 会去 PATH 环境变量指定的目录中查找:

echo $PATH
# /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
输入:script.py
  ↓
Shell 依次搜索:
  /usr/local/bin/script.py  ❌ 不存在
  /usr/bin/script.py        ❌ 不存在
  /bin/script.py            ❌ 不存在
  /usr/sbin/script.py       ❌ 不存在
  /sbin/script.py           ❌ 不存在
  ↓
找不到!报错:command not found
“./” 的含义

加了 “./ ” 就是明确告诉 Shell:"不要去 PATH 里找,直接执行当前目录下的这个文件!"

.   →  当前目录
/   →  路径分隔符

./script.py  =  当前目录下的 script.py
./script.py
# 等价于
/home/user/projects/script.py   # 使用绝对路径也可以
完整执行流程对比
# ❌ 错误方式
script.py
# Shell: 去 PATH 找 script.py → 找不到 → command not found

# ✅ 正确方式一:相对路径
./script.py
# Shell: 直接执行当前目录的 script.py → 读取 shebang → 用 python3 执行

# ✅ 正确方式二:绝对路径
/home/user/script.py
# Shell: 直接执行指定路径的文件

# ✅ 正确方式三:显式指定解释器(无需 shebang,无需 ./)
python3 script.py
# Shell: 去 PATH 找 python3 ✅ → 用 python3 执行 script.py
如果想直接输入 script.py 执行怎么办?

把脚本所在目录加入 PATH(或把脚本放到已有的 PATH 目录中):

# 方法一:把脚本复制/移动到 PATH 目录
cp script.py /usr/local/bin/script.py
script.py    # ✅ 可以直接执行

# 方法二:临时添加当前目录到 PATH(不推荐长期使用)
export PATH="$PATH:$(pwd)"
script.py    # ✅ 可以直接执行

# 方法三:去掉 .py 后缀,更像一个"命令"
cp script.py /usr/local/bin/myscript
myscript     # ✅ 更优雅

但是不要把当前目录 . 放在 PATH 里。把 . 加入 PATH,是不安全的做法:

# 危险场景:假设当前目录 . 在 PATH 中
# 攻击者在某目录(比如 /tmp)下放了一个恶意文件,命名为 ls

cd /tmp
# 在当前目录里执行 ls, 由于当前目录. 在PATH里,会找到恶意脚本 /tmp/ls
ls        # 😱 执行的是恶意脚本,而不是系统的 ls!

# 所以当前目录 . 默认不加入 PATH

3. 什么时候需要 Shebang

3.1 需要加 Shebang 的情况

1. 作为独立可执行脚本(命令行工具)时,需要添加:

#!/usr/bin/env python3
# 作为独立可执行脚本(命令行工具)

# 典型场景:
# - 系统管理脚本
# - CLI 工具
# - 放在 /usr/local/bin/ 下的命令
# - 自动化脚本(定时任务、部署脚本等)
# 用户直接运行py文件,不想每次都打 python3
./backup.py
./deploy.py

3.2 不需要加 Shebang 的情况

1. 作为模块被导入:

# 1. 作为模块被导入
# mymodule.py —— 不需要 shebang
def add(a, b):
    return a + b

2. 在 IDE 中运行(PyCharm、VSCode 等):

# 2. 在 IDE 中运行(PyCharm、VSCode 等)
# IDE 自己管理解释器,shebang 无意义

3. 明确用 python 命令执行:

# 3. 明确用 python 命令执行
python3 script.py   # 已经指定了解释器

4. Windows 系统(原生不支持 shebang)

# 4. Windows 系统(原生不支持 shebang)
# Windows 的 .py 文件通过文件关联打开
# 虽然 Python Launcher(py.exe) 支持读取 shebang
# 但通常不依赖它

3.3 总结

场景 是否需要 Shebang
直接 ./script.py 执行 ✅ 必须
python3 script.py 执行 ❌ 不需要
作为模块 import ❌ 不需要
IDE 中运行 ❌ 不需要
Linux/macOS CLI 工具 ✅ 推荐
Windows 脚本 ⚠️ 可选

更多推荐