环境搭建与第一个脚本 (Setup & First Script)
章节概述
本章从零开始搭建 Bash 开发环境,理解脚本文件的本质,编写并运行第一个 Shell 脚本。通过与 C 语言程序的对比,建立”解释型语言 vs 编译型语言”的直觉认知。
核心理念:脚本不是程序,而是给 Shell 看的”操作清单”。理解解释执行的流程,是掌握 Bash 的第一步。
第1节:Bash 的安装与版本确认
大多数 Linux 发行版已预装 Bash,macOS 默认使用 zsh 但可切换为 Bash。
# 查看当前 shell
echo $SHELL
# 查看 bash 版本
bash --version
# 查看 bash 路径
which bash
# 输出: /bin/bash 或 /usr/bin/bash不同平台的安装方式:
| 平台 | 命令 | 备注 |
|---|---|---|
| Ubuntu/Debian | sudo apt install bash | 通常已预装 |
| CentOS/RHEL | sudo yum install bash | 通常已预装 |
| macOS | brew install bash | Homebrew 安装新版本 |
| Windows (WSL) | 在 WSL 发行版中自动安装 | 推荐使用 WSL2 |
注意:macOS 的 Bash 版本较旧(3.2),因 GPLv3 许可证问题。推荐通过 Homebrew 安装新版。
第2节:Shebang —— 脚本的身份证
文件的第一行 #! 称为 shebang,告诉系统用哪个解释器来执行。
#!/bin/bash
# 这是标准的 bash shebang
#!/usr/bin/env bash
# 推荐写法:自动搜索 PATH 中的 bash,更具可移植性C 语言对比:
// C 程序不需要 shebang,因为它是编译型语言
// 编译后直接生成可执行的二进制文件
#include <stdio.h>
int main() {
printf("Hello, C World!\n");
return 0;
}
// 编译: gcc -o hello hello.c
// 运行: ./hello核心差异:C 编译为二进制后直接执行;Bash 脚本由解释器逐行读取并执行。
第3节:编辑器选择
| 编辑器 | 适用场景 | 学习曲线 |
|---|---|---|
vim | 远程服务器编辑,功能强大 | 陡峭 |
nano | 快速简单编辑,适合新手 | 平缓 |
VS Code | 本地开发,智能提示 | 中等 |
emacs | 可扩展性强,集成终端 | 陡峭 |
推荐配置 VS Code Bash 扩展:
- ShellCheck:静态语法检查
- Bash Extension:语法高亮和自动补全
第4节:chmod +x —— 赋予执行权限
# 创建第一个脚本
cat > hello.sh << 'EOF'
#!/usr/bin/env bash
echo "Hello, Bash World!"
EOF
# 赋予执行权限
chmod +x hello.sh
# 查看权限变化
ls -l hello.sh
# -rwxr-xr-x 1 user user ... hello.sh权限位含义:
| 位置 | 权限 | 含义 |
|---|---|---|
| 第1位 | rwx | 文件所有者:读、写、执行 |
| 第2位 | r-x | 所属组:读、执行 |
| 第3位 | r-x | 其他用户:读、执行 |
第5节:运行脚本的三种方式
# 方式1: 直接执行(需要 +x 权限)
./hello.sh
# 方式2: 作为 bash 的参数(不需要 +x 权限)
bash hello.sh
# 方式3: source 或 .(在当前 shell 环境中执行)
source hello.sh
. hello.sh三种方式的区别:
| 方式 | 子进程 | 环境变量 | 需要 +x |
|---|---|---|---|
./script.sh | 是(子 shell) | 不继承 | 是 |
bash script.sh | 是(子 shell) | 不继承 | 否 |
source script.sh | 否(当前 shell) | 继承 | 否 |
关键理解:
source在当前进程中执行,变量修改会影响当前环境。直接执行或bash执行则在子进程中运行,隔离安全。
第6节:第一个完整脚本
#!/usr/bin/env bash
#===============================================
# 脚本名称: hello.sh
# 功能描述: 打印问候语
# 作者: Your Name
# 日期: 2026-01-01
#===============================================
# 获取当前时间
CURRENT_HOUR=$(date +%H)
# 根据时间输出不同问候
if [ "$CURRENT_HOUR" -lt 12 ]; then
GREETING="早上好"
elif [ "$CURRENT_HOUR" -lt 18 ]; then
GREETING="下午好"
else
GREETING="晚上好"
fi
echo "${GREETING},欢迎学习 Bash!"
echo "当前时间: $(date '+%Y-%m-%d %H:%M:%S')"C 语言对比(等效功能):
#include <stdio.h>
#include <time.h>
int main() {
time_t t = time(NULL);
struct tm *tm_info = localtime(&t);
int hour = tm_info->tm_hour;
if (hour < 12) {
printf("早上好");
} else if (hour < 18) {
printf("下午好");
} else {
printf("晚上好");
}
printf(",欢迎学习 C!\n");
return 0;
}第7节:常见错误排查
| 错误信息 | 原因 | 解决方案 |
|---|---|---|
Permission denied | 缺少执行权限 | chmod +x script.sh |
bad interpreter: /bin/bash^M | Windows 换行符 | dos2unix script.sh 或 sed -i 's/\r$//' script.sh |
command not found | 未使用 shebang 或 PATH 问题 | 使用 #!/usr/bin/env bash |
第8节:课后练习
- 创建一个脚本
myinfo.sh,输出你的用户名、当前日期、所在目录 - 尝试用
./myinfo.sh、bash myinfo.sh、source myinfo.sh三种方式运行,观察区别 - 在脚本中修改
PATH变量,分别用三种方式运行后,检查echo $PATH的变化
相关章节: