环境准备:Linux系统、Shell版本、编辑器与脚本执行

Shell脚本编程的第一课,不是写第一行 echo,而是把“工作台”搭对。很多初学者在Windows上写完脚本,传到Linux服务器上却无法执行,或者明明写了正确的语法却报错,根源往往不在代码本身,而在环境差异、解释器选择、文件编码或权限设置上。本章将系统梳理Linux系统选型、Bash与Zsh的差异、编辑器选择策略、脚本执行权限与运行方式,帮助你建立一套稳定、可复现的脚本开发环境。

Shell脚本开发环境全景图 Linux系统选择 CentOS/RHEL Ubuntu/Debian Alpine (BusyBox) Shell解释器 Bash (默认) Zsh (增强交互) sh (POSIX兼容) 编辑器选择 Vim/Neovim VS Code + Remote Sublime Text 执行方式 bash script.sh ./script.sh source script.sh 核心要素:文件权限与执行位 chmod +x script.sh → ls -l 查看权限 → shebang (#!/bin/bash) 指定解释器 常见问题排查 • 权限不足:Permission denied → chmod +x • 换行符错误:CRLF → 使用 dos2unix 转换 • 解释器错误:bad interpreter → 检查 shebang • 编码问题:UTF-8 BOM → 去除 BOM 头 最佳实践建议 • 统一使用 Bash 5.x 版本 • 脚本开头加 set -euo pipefail • 使用 shellcheck 做静态检查 • 开发环境与生产环境保持一致

核心原理:理解Shell脚本的运行环境

Shell脚本本质上是一个文本文件,其中包含一系列命令和逻辑控制语句。当你在终端执行一个脚本时,操作系统需要完成三件事:找到解释器、读取文件内容、逐行执行命令。这三件事分别对应三个关键环境要素:系统类型(决定默认Shell和命令集)、解释器版本(决定语法支持范围)、文件权限(决定是否允许执行)。

Linux系统与macOS、Windows的差异不仅体现在内核上,更体现在用户空间工具链。例如,sed 在GNU版本和BSD版本之间存在参数差异,grep 的 -P 选项在macOS上默认不可用。因此,脚本开发必须明确目标运行平台,并在脚本头部注释中声明。

Shell解释器方面,Bash(Bourne Again Shell)是Linux发行版的事实标准,几乎每个发行版都预装。Zsh在交互式体验上更优(自动补全、拼写纠正),但脚本兼容性不如Bash。对于生产环境脚本,建议以Bash为目标解释器,并确保脚本头部使用 #!/bin/bash 明确指定。

判断方法:选择Linux发行版与Shell版本

选择Linux发行版时,需要根据使用场景判断:

场景 推荐发行版 理由
企业服务器 CentOS Stream / RHEL / Rocky Linux 稳定性高,安全更新周期长,与生产环境一致
开发测试 Ubuntu LTS / Debian 软件包新,社区活跃,apt安装方便
容器镜像 Alpine 体积小(5MB),但需注意BusyBox的语法差异
个人学习 任何发行版 + 虚拟机 建议使用虚拟机隔离,避免影响宿主机

检查当前Shell版本,可以使用以下命令:

# 查看当前Shell类型
echo $SHELL

# 查看Bash版本
bash --version

# 查看Zsh版本
zsh --version

# 查看系统默认Shell
cat /etc/passwd | grep $(whoami)
经验提醒:如果脚本需要在多个Linux发行版上运行,建议在脚本开头添加兼容性检查。例如,检测 grep -P 是否可用,不可用时回退到 grep -E。

操作流程:编辑器选择与配置

编辑器是脚本开发的“主战场”。对于Shell脚本,推荐以下三种方案:

  1. Vim/Neovim:终端内编辑,轻量高效,适合服务器远程开发。配置语法高亮和自动缩进后,体验极佳。
  2. VS Code + Remote-SSH:图形化界面,支持智能提示、断点调试、Git集成。适合本地开发远程部署。
  3. Sublime Text:轻量快速,启动迅速,适合快速修改小脚本。

无论选择哪种编辑器,都需要确保以下配置:

  • 使用UTF-8无BOM编码保存文件
  • 换行符使用LF(Unix风格),而非CRLF(Windows风格)
  • 开启Shell语法高亮(Vim中 :syntax on)
  • 设置Tab为4个空格(或保持Tab,但需统一)

在Vim中,可以创建 ~/.vimrc 配置文件:

" 基础设置
set number
set tabstop=4
set shiftwidth=4
set expandtab
syntax on
filetype plugin indent on

" 自动检测Shell脚本
autocmd BufNewFile *.sh set filetype=sh

案例拆解:从零搭建一个可执行的脚本

下面通过一个实际案例,完整演示从编写到执行的整个过程。假设我们需要编写一个系统信息收集脚本 sysinfo.sh,用于输出CPU、内存和磁盘使用情况。

第一步:创建脚本文件

vim sysinfo.sh

第二步:编写脚本内容

#!/bin/bash
# 系统信息收集脚本
# 作者: 课程示例
# 日期: 2025-01-15

echo "===== 系统信息 ====="
echo "主机名: $(hostname)"
echo "内核版本: $(uname -r)"
echo "当前用户: $(whoami)"
echo ""
echo "===== CPU 信息 ====="
lscpu | grep "Model name" | head -1
echo "CPU核心数: $(nproc)"
echo ""
echo "===== 内存信息 ====="
free -h | grep Mem | awk '{print "总内存: "$2, "已用: "$3, "可用: "$4}'
echo ""
echo "===== 磁盘信息 ====="
df -h / | tail -1 | awk '{print "根分区: 总容量"$2, "已用"$3, "可用"$4, "使用率"$5}'

第三步:设置执行权限

chmod +x sysinfo.sh

第四步:执行脚本

# 方式一:直接执行(需要执行权限)
./sysinfo.sh

# 方式二:通过Bash解释器执行(无需执行权限)
bash sysinfo.sh

# 方式三:使用source执行(在当前Shell中运行)
source sysinfo.sh

第五步:验证结果

===== 系统信息 =====
主机名: dev-server-01
内核版本: 5.15.0-91-generic
当前用户: root

===== CPU 信息 ====
Model name: Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz
CPU核心数: 8

===== 内存信息 ====
总内存: 15G 已用: 2.3G 可用: 12G

===== 磁盘信息 ====
根分区: 总容量98G 已用35G 可用58G 使用率36%

这个案例展示了三种执行方式的区别:./sysinfo.sh 需要执行权限且使用shebang指定的解释器;bash sysinfo.sh 显式指定解释器,无需执行权限;source sysinfo.sh 在当前Shell进程中执行,可以保留变量和函数定义。

常见误区与总结复盘

在环境准备阶段,初学者最容易犯以下错误:

风险提示:
  • 误区一:在Windows上编写脚本直接上传。Windows默认使用CRLF换行,Linux下执行会报 bad interpreter: /bin/bash^M。解决方法是使用 dos2unix 转换,或在Vim中执行 :set ff=unix。
  • 误区二:忽略shebang行。如果脚本没有 #!/bin/bash,系统会使用当前用户的默认Shell执行,可能导致语法不兼容。
  • 误区三:权限设置过宽。直接 chmod 777 script.sh 虽然能执行,但存在安全隐患。建议使用 chmod 755(所有者可读写执行,组和其他用户可读执行)。
  • 误区四:使用 sh script.sh 执行Bash脚本。在Ubuntu等系统上,sh 指向 dash,不支持Bash的数组、关联数组等高级特性。

总结本章要点:环境准备的核心是“三个一致”——系统环境一致、解释器版本一致、文件格式一致。建议在项目目录下创建 scripts/ 文件夹统一存放脚本,并编写一个 README.md 记录每个脚本的用途、依赖和执行方式。对于团队协作,可以使用 shellcheck 工具做静态检查,确保代码质量。

实战建议:在正式编写业务脚本前,先花10分钟验证环境。执行 bash --version 确认版本,echo $SHELL 确认默认Shell,which bash 确认解释器路径。这些基础检查能避免后续80%的环境类报错。