人人都会AI编程

13.1 脚本结构与执行

更新时间:2026-07-12

Shell 脚本本质上就是把一系列需要在终端中手动输入的命令,按顺序写进一个纯文本文件里,让系统一次性自动执行。掌握脚本的基本结构和正确的执行方式,是学习 Shell 编程的第一步。

1. 脚本的基本结构

一个典型的 Shell 脚本通常包含以下几个部分:

#!/bin/bash

# 脚本名称:backup.sh
# 功能描述:将 /home/user/documents 目录打包备份
# 作者:your_name
# 日期:2025-01-20

# 定义变量
SOURCE_DIR="/home/user/documents"
BACKUP_FILE="/tmp/backup_$(date +%Y%m%d).tar.gz"

# 执行备份命令
tar -czf "$BACKUP_FILE" "$SOURCE_DIR"

# 检查命令是否成功,并输出相应提示
if [ $? -eq 0 ]; then
    echo "备份成功:$BACKUP_FILE"
else
    echo "备份失败,请检查权限或磁盘空间。" >&2
    exit 1
fi

逐段解释:

  • Shebang 行(#!/bin/bash:必须是脚本的第一行,告诉系统用哪个解释器来执行这个脚本。#!/bin/bash 表示用 Bash 执行,你也可以根据需要指定 #!/bin/sh#!/usr/bin/python3 等。缺少这一行时,脚本通常仍可在当前 Shell 中执行,但明确指定能避免跨环境兼容问题。
  • 注释(以 # 开头):从 # 到行尾的内容会被忽略,用于记录脚本用途、变量含义或注意事项。良好的注释习惯能让你或他人在几个月后还能看懂脚本的逻辑。
  • 命令序列:就像直接在终端输入一样,脚本会从上到下逐行执行这些命令。你可以使用变量(如 $SOURCE_DIR)、命令替换(如 $(date +%Y%m%d))、条件判断(if ... then ... fi)等语法,让脚本更灵活。
  • 退出状态:脚本中的命令执行后会返回一个退出码($? 获取上一条命令的返回值),0 通常代表成功,非 0 代表错误。通过检查退出码,脚本可以决定后续流程,并在必要时用 exit 主动结束,返回特定状态。

2. 执行 Shell 脚本的几种方式

假设你已经写好了一个脚本文件 myscript.sh,可以使用以下方式执行:

  • 方式一:直接以可执行文件运行
  # 先赋予执行权限(只需一次)
  chmod +x myscript.sh
  # 然后在脚本所在目录下运行
  ./myscript.sh
  

这种方式需要一个正确的 Shebang 行,且脚本必须拥有可执行权限(chmod +x)。./ 表示在当前目录寻找该文件,因为出于安全考虑,当前目录通常不在 PATH 环境变量中。这是最标准的用法,适合分发和部署脚本。

  • 方式二:显式调用解释器执行
  bash myscript.sh
  

直接调用 bash(或 shpython 等)并传入脚本路径。这种方式不需要脚本有可执行权限,也会忽略 Shebang 行(因为解释器已经明确指定)。它很适合在测试阶段快速运行,或当脚本权限无法更改时使用。

  • 方式三:使用 source(或 .)在当前 Shell 中执行
  source myscript.sh
  # 或者
  . myscript.sh
  

source 会让脚本中的每一条命令都在当前 Shell 进程中运行,而不是开启一个子 Shell。这带来的关键区别是:脚本中定义的变量、修改的环境变量(例如 export)、切换的目录(cd)都会保留并影响你当前的终端会话。通常用于加载环境配置文件(如 ~/.bashrc 的修改后,执行 source ~/.bashrc)或定义一些需要保留在 Shell 中的函数和别名。

3. 实用建议

  • 脚本命名与位置:将常用脚本放在 ~/bin//usr/local/bin/ 目录下,并确保这些目录在 PATH 中,以后就可以像系统命令一样直接输入脚本名运行。
  • 调试技巧:如果脚本运行结果不符合预期,可以加上 -x 选项来跟踪执行过程:
  bash -x myscript.sh
  

这会将每条被执行的命令及其展开结果输出到终端,是排错时最直接有效的手段。

  • 安全性:不要随意执行来源不明的脚本,尤其是那些需要 sudo 权限的。运行前先用 catless 大致浏览内容,确认没有恶意命令。

掌握了脚本的基本结构和执行方法后,你就能将日常重复性工作固化为可复用的工具,迈出自动化运维的第一步。