环境准备:Linux系统、Shell版本、编辑器与脚本执行
Shell脚本编程的第一课,不是写第一行 echo,而是把“工作台”搭对。很多初学者在Windows上写完脚本,传到Linux服务器上却无法执行,或者明明写了正确的语法却报错,根源往往不在代码本身,而在环境差异、解释器选择、文件编码或权限设置上。本章将系统梳理Linux系统选型、Bash与Zsh的差异、编辑器选择策略、脚本执行权限与运行方式,帮助你建立一套稳定、可复现的脚本开发环境。
核心原理:理解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)
grep -P 是否可用,不可用时回退到 grep -E。
操作流程:编辑器选择与配置
编辑器是脚本开发的“主战场”。对于Shell脚本,推荐以下三种方案:
- Vim/Neovim:终端内编辑,轻量高效,适合服务器远程开发。配置语法高亮和自动缩进后,体验极佳。
- VS Code + Remote-SSH:图形化界面,支持智能提示、断点调试、Git集成。适合本地开发远程部署。
- 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 工具做静态检查,确保代码质量。
bash --version 确认版本,echo $SHELL 确认默认Shell,which bash 确认解释器路径。这些基础检查能避免后续80%的环境类报错。