15%

全场主机优惠15%

测试技能,享折扣

使用代码:

Skills
开始使用
01.11.2024
1 +1

理解Shebangs:在Linux终端中执行Bash和Python脚本

如果你曾在 Linux 上编写过 shell 或 Python 脚本,并想知道系统如何知道使用哪个解释器——答案在于文件顶部一个微小但强大的两字符序列:**shebang**(#!)。

无论你是在自动化服务器维护任务、在 VPS Hosting 环境中管理部署,还是为 Web 服务器编写实用脚本,理解 shebang 的工作原理是每个系统管理员和开发人员都应该掌握的基础 Linux 技能。

本指南涵盖你需要了解的一切:什么是 shebang、如何在 Bash 和 Python 脚本中使用它们,以及将业余脚本与生产就绪自动化区分开来的最佳实践。

什么是 Shebang(#!)?

**shebang**(也写作 *sha-bang*、*hashbang* 或 *pound-bang*)是放在脚本文件第一行的特殊字符序列。它告诉 Linux 内核应该使用哪个解释器来执行文件的其余部分。

语法很简单:

#!/path/to/interpreter

当你运行脚本时,操作系统读取文件的前两个字节。如果找到 #!,它会将文件传递给该行指定的解释器。没有 shebang,shell 可能会尝试使用自己的内置解释器执行脚本——这可能导致意外行为或彻底失败,特别是在混合语言时。

常见 Shebang 示例

脚本类型Shebang 行
Bash#!/bin/bash
POSIX Shell#!/bin/sh
Python 3#!/usr/bin/env python3
Python 2(旧版)#!/usr/bin/env python2
Perl#!/usr/bin/perl
Ruby#!/usr/bin/env ruby
Node.js#!/usr/bin/env node

为什么 /usr/bin/env 很重要

你会经常看到 shebang 以两种不同的风格编写:

#!/bin/python3

与:

#!/usr/bin/env python3

第二种形式几乎总是首选。原因如下:

  • 可移植性python3 的位置在 Linux 发行版、macOS 和 BSD 系统中可能不同。/usr/bin/env 搜索用户的 $PATH 来找到正确的解释器,无论它安装在哪里。
  • 虚拟环境:使用 Python 虚拟环境(venv)时,/usr/bin/env python3 会正确解析到 virtualenv 的 Python 二进制文件,而不是系统的。
  • 面向未来:如果解释器被更新或重新定位,使用 env 的脚本无需修改即可继续工作。

只有当你特别需要保证使用特定的二进制文件时,才应该使用硬编码的绝对路径(例如 #!/bin/bash)——例如,在安全敏感的脚本中,$PATH 操纵可能是一个风险。

在 Bash 脚本中使用 Shebang:分步指南

让我们逐步完成从头开始创建完整、可执行的 Bash 脚本的过程。

步骤 1:打开终端

直接访问你的终端或通过 SSH 连接到你的 Linux 服务器。

步骤 2:创建新的 Bash 脚本文件

使用文本编辑器(如 nano)创建新文件:

nano myscript.sh

步骤 3:添加 Shebang 和脚本内容

在文件的最顶部,添加 shebang 行,然后是你的脚本逻辑:

#!/bin/bash

# A simple greeting script
echo "Hello, World!"
echo "Current date and time: $(date)"
echo "Running as user: $(whoami)"

步骤 4:保存并退出

nano 中,按 CTRL + X,然后 Y,然后 Enter 来保存并关闭文件。

步骤 5:使脚本可执行

默认情况下,新创建的文件不可执行。使用 chmod 授予执行权限:

chmod +x myscript.sh

你可以使用以下命令验证权限更改:

ls -l myscript.sh

你应该看到类似的输出:

-rwxr-xr-x 1 user user 112 Jun 10 14:32 myscript.sh

步骤 6:运行脚本

从终端直接执行脚本:

./myscript.sh

预期输出:

Hello, World!
Current date and time: Tue Jun 10 14:32:01 UTC 2025
Running as user: youruser

> 注意:./ 前缀告诉 shell 在当前目录中查找脚本。如果你的脚本目录已添加到 $PATH,你可以仅按名称运行脚本。

在 Python 脚本中使用 Shebang:分步指南

Python 脚本遵循相同的模式,推荐的 shebang 行有一个关键区别。

步骤 1:创建新的 Python 脚本文件

nano myscript.py

步骤 2:添加 Shebang 和 Python 代码

#!/usr/bin/env python3

# A simple Python script demonstrating shebang usage
import sys
import platform

print("Hello from Python!")
print(f"Python version: {sys.version}")
print(f"Platform: {platform.system()} {platform.release()}")

步骤 3:保存、退出并使其可执行

# Save and exit nano with CTRL+X, Y, Enter
chmod +x myscript.py

步骤 4:运行脚本

./myscript.py

预期输出:

Hello from Python!
Python version: 3.11.2 (main, Mar 13 2023, 12:18:29)
Platform: Linux 5.15.0-76-generic

注意你不需要在命令前加上 python3——shebang 会自动处理解释器选择。

实际现实世界示例

单独理解 shebang 很有用,但将其应用于实际管理任务会使其价值更加清晰。

Bash:自动化备份脚本

#!/bin/bash

# Automated backup script for web files
BACKUP_DIR="/var/backups/webfiles"
SOURCE_DIR="/var/www/html"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
BACKUP_FILE="$BACKUP_DIR/backup_$TIMESTAMP.tar.gz"

mkdir -p "$BACKUP_DIR"
tar -czf "$BACKUP_FILE" "$SOURCE_DIR"

echo "Backup completed: $BACKUP_FILE"

Python:系统健康检查脚本

#!/usr/bin/env python3

import shutil
import psutil

def check_disk_usage(path="/"):
    total, used, free = shutil.disk_usage(path)
    percent_used = (used / total) * 100
    print(f"Disk Usage ({path}): {percent_used:.1f}% used")
    if percent_used > 85:
        print("WARNING: Disk usage is critically high!")

def check_memory():
    mem = psutil.virtual_memory()
    print(f"Memory Usage: {mem.percent}% used")

check_disk_usage()
check_memory()

这些类型的脚本在管理基础设施时非常宝贵——无论你是运行单个 Shared Web Hosting 账户还是在 Dedicated Servers 上编排工作负载。

Shebang 行为:幕后发生了什么

当你执行带有 shebang 的脚本时,Linux 内核执行以下步骤:

  1. 读取文件的第一行并识别 #! 序列。
  2. 解析解释器路径(和任何可选参数)从 shebang 行。
  3. 调用解释器,将脚本文件作为参数传递。

例如,运行 ./myscript.py 在内部等同于:

/usr/bin/env python3 ./myscript.py

这就是为什么 shebang 必须始终在**第一行**,**没有前导空格**——即使在它之前有一个空行也会导致 shebang 被忽略。

没有 Shebang 会发生什么?

如果没有 shebang,行为取决于脚本的调用方式:

  • 如果作为 ./script.py 运行,当前 shell(例如 Bash)会尝试解释它,这对 Python 代码会失败。
  • 如果作为 python3 script.py 运行,shebang 无关——Python 被明确指定。
  • 如果作为 bash script.sh 运行,同样 shebang 被绕过。

shebang 仅在脚本**直接**执行时才重要(即作为 ./script)。

高级 Shebang 技术

向解释器传递参数

你可以通过 shebang 行向解释器传递标志:

#!/bin/bash -e

-e 标志导致 Bash 在任何命令失败时立即退出——这是生产脚本的常见安全实践。

#!/usr/bin/env python3 -u

-u 标志在 Python 中强制无缓冲输出,对实时日志记录很有用。

> 注意:某些系统在 shebang 行中的解释器路径后仅支持单个参数。对于复杂的参数传递,最好在脚本本身内设置选项(例如 Bash 中的 set -euo pipefail)。

使用 env 与特定版本

#!/usr/bin/env python3.11

这针对特定的 Python 版本,在存在多个版本的环境中很有用。

多语言脚本

在某些高级情况下,开发人员编写同时在多种语言中有效的脚本。shebang 通过控制首先运行哪个解释器来启用这一点。虽然这是一个小众技术,但它展示了 shebang 提供的灵活性。

编写 Shebang 行的最佳实践

遵循这些最佳实践将使你的脚本更加健壮、可移植和可维护——这在生产服务器环境中特别重要。

1. 始终使用正确的解释器

将 shebang 与你的脚本需要的语言和版本相匹配:

#!/bin/bash          # For Bash-specific syntax
#!/bin/sh            # For POSIX-compliant shell scripts (more portable)
#!/usr/bin/env python3  # For Python 3 scripts

永远不要假设 /bin/sh/bin/bash 是可互换的——它们不是。Bash 支持 POSIX sh 不支持的功能(数组、[[ ]]、进程替换)。

2. 为了可移植性优先使用 /usr/bin/env

如前所述,使用 env 使脚本在不同系统和 Python 虚拟环境中可移植。仅在安全或特定性要求时使用硬编码路径。

3. 始终设置执行权限

没有执行权限的脚本会因”权限被拒绝”错误而失败:

chmod +x script.sh
chmod +x script.py

对于系统上所有用户的脚本:

chmod 755 script.sh

4. 在专用目录中组织脚本

为个人脚本创建 ~/scripts~/bin 目录并将其添加到你的 $PATH

mkdir -p ~/bin
echo 'export PATH="$HOME/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

之后,放在 ~/bin 中的任何可执行脚本都可以从任何地方按名称运行。

5. 添加有意义的注释

用解释其目的、用法和任何依赖项的注释记录你的脚本:

#!/bin/bash
# Script: backup_web.sh
# Purpose: Creates timestamped backups of web root
# Usage: ./backup_web.sh
# Dependencies: tar, gzip
# Author: Your Name
# Last Modified: 2025-06-10

6. 为更安全的 Bash 脚本使用 set 选项

对于生产 Bash 脚本,在 shebang 之后立即添加这些安全选项:

#!/bin/bash
set -euo pipefail
  • -e:出错时退出
  • -u:将未设置的变量视为错误
  • -o pipefail:捕获管道命令中的错误

7. 在部署到生产前测试脚本

始终在开发或暂存环境中测试脚本,然后再在生产服务器上运行它们。如果你需要一个隔离的测试环境,VPS Hosting 计划提供了一个经济实惠的、一次性的沙箱,镜像生产条件。

排除常见 Shebang 问题

“权限被拒绝”错误

bash: ./myscript.sh: Permission denied

解决方案:脚本缺少执行权限。运行 chmod +x myscript.sh

“没有这样的文件或目录”错误

bash: ./myscript.py: /usr/bin/env: bad interpreter: No such file or directory

解决方案:shebang 中指定的解释器在该路径不存在。使用 which python3which bash 验证。

脚本使用错误的解释器运行

症状:运行 .sh 文件时出现 Python 语法错误,反之亦然。

解决方案:确保 shebang 行在第 1 行,没有前导空格或空行,并且它指向正确的解释器。

Windows 行尾(rn

如果你在 Windows 上编辑脚本并将其传输到 Linux,Windows 风格的行尾可能会破坏 shebang:

/bin/bash^M: bad interpreter

解决方案:使用 dos2unix 转换行尾:

dos2unix myscript.sh

服务器管理背景下的 Shebang

对于任何管理基于 Linux 的托管基础设施的人来说,脚本编写流畅性是不可协商的。Shebang 是自动化的入口点——从简单的 cron 作业到复杂的部署管道。

15%

全场主机优惠15%

测试技能,享折扣

使用代码:

Skills
开始使用