shell
一句话定义:
Shell 是用户与 Linux 内核之间的“命令解释器 + 控制器”
它本身是一个用户空间程序,不是内核。
用户 -> Shell -> 系统调用 -> Kernel -> 硬件
+-------------------------------+
| 应用程序 / 服务 |
| (nginx / mysql / docker) |
+-------------------------------+
| Shell / 脚本 |
| bash / sh / zsh / fish |
+-------------------------------+
| libc / system calls |
+-------------------------------+
| Linux Kernel |
+-------------------------------+
| Hardware |
+-------------------------------+
Shell 的本质:
- 解析命令
- 管理进程
- 控制 IO
- 协调程序运行
| Shell | 特点 | 使用场景 |
|---|---|---|
| bash | 标准、稳定 | 服务器默认 |
| sh | POSIX 兼容 | 脚本可移植 |
| zsh | 交互友好 | 桌面 / 开发 |
| fish | 易用但不兼容 | 个人使用 |
| dash | 极快 | Debian /bin/sh |
📌 生产环境脚本:bash / sh
ls -l /etc
Shell 做了什么:
- 分词(tokenize)
- 变量替换
- 通配符展开
- 执行命令
前台 / 后台
cmd &
jobs
fg %1
子进程 / 父进程
cmd1 | cmd2
每个 | 都是一个进程
cmd > out.log 2>&1
cmd < input.txt
cmd >> file
| FD | 含义 |
|---|---|
| 0 | stdin |
| 1 | stdout |
| 2 | stderr |
变量类型
var=1 # shell 变量
export var=1 # 环境变量
子进程只能继承环境变量
a=10
echo "$a" # 推荐
echo '$a' # 原样输出
if [ -f /etc/passwd ]; then
echo ok
fi
注意:
- [ 是命令
- 空格不能少
for i in 1 2 3; do
echo $i
done
foo() {
echo hello
}
cmd
echo $? # 0 = 成功
Shell 自动使用上一个命令的退出码
Shell 并不“执行命令”,而是:
fork() -> execve() -> 内核调度
Shell 的职责:
- 创建进程
- 设置 IO
- 传参
- 等待或后台
script.sh
实际流程:
- Shell fork 自己
- exec 指定解释器(shebang)
- 逐行执行
- 结束返回 exit code
#!/usr/bin/env bash
决定脚本由谁解释
| 类型 | 场景 | 加载文件 |
|---|---|---|
| login shell | ssh 登录 | /etc/profile |
| non-login | 开终端 | ~/.bashrc |
| 非交互 | 脚本 | 只加载脚本 |
| 文件 | 作用 |
|---|---|
| /etc/profile | 全局环境 |
| ~/.bashrc | 用户环境 |
| ~/.bash_profile | 登录环境 |
| /etc/bashrc | 系统 bash 配置 |
| /etc/inputrc | 键盘行为 |
自动化
backup.sh
deploy.sh
cleanup.sh
系统初始化
sysctl
limits
systemd
应急修复
- rescue 模式
- rd.break
- ❌ 变量不加引号
- ❌ 用 for i in $(ls)
- ❌ 忽略 exit code
- ❌ 混用 bash/sh 特性
- ❌ 脚本无 set -e 防护
#!/usr/bin/env bash
set -Eeuo pipefail
| 选项 | 含义 |
|---|---|
| -e | 出错即停 |
| -u | 未定义变量报错 |
| -o pipefail | 管道失败可感知 |
Shell 不是“命令集合”,而是 Linux 系统的“编排语言”和“控制中枢”。