2026年01月20日/ 浏览 11
适读人群:对 Linux 已能进行日常操作,希望系统性掌握 Shell 编程的技术人;亦适合作为团队内部每日学习打卡材料。
目标效果:30 天写完 30 个脚本,掌握 50 + 关键技巧,能独立开发、调试、部署生产级脚本。
一、环境与工具
必备
说明
上手步骤
Linux 发行版
推荐 Ubuntu 22.04 / Rocky Linux 9
docker run -it --rm ubuntu:22.04 bash
Shell
/bin/bash ≥ 5.x
先执行 bash --version
编辑器
VS Code + Bash IDE / Vim + bash-language-server
VS Code:安装 Bash IDE 插件
质量保障
shellcheck + shfmt
sudo apt install shellcheck shfmt
版本控制
Git
git init shell-30days && git add . && git commit -m "Day0 init"
二、学习节奏总览
Week 1:握手阶段 – 了解语法、变量、流程控制Week 2:自动化阶段 – 文件批处理、网络与文本处理Week 3:体系化阶段 – 函数、日志、错误处理、性能优化Week 4:生产级阶段 – 并发、守护进程、系统监控、CI/CD 集成Day 30:毕业项目 – 交付一份可落地的综合脚本三、30 天每日任务
写法约定
新建 dayXX.sh,开头写 #!/usr/bin/env bash;完成脚本后 chmod +x dayXX.sh && ./dayXX.sh 验证功能;shellcheck dayXX.sh 确保无警告,git commit -am "DayXX" 留痕。Week 1 · 基础打牢
Day
主题与目标
关键脚本片段
操作要点
1
Hello World、注释与可执行
echo "Hello, $USER"
chmod +x,用 set -x 观察执行流
2
变量与读写
read -rp "Your Name: " name
演示 export 与局部变量区别
3
条件判断
[[ -f "$1" ]] && echo "file"
[[ … ]]优先于[ … ]
4
for/while
for f in *.log; do …; done
处理空格文件名用 IFS=$\n
5
case 语句
`case $1 in start
stop) … ;; esac`
6
数学与日期
echo $((RANDOM%10))
date -d +3 days +%F
7
debug 基础
bash -xv ./day07.sh
介绍 trap echo ERROR ERR
Week 2 · 自动化进阶
Day
主题与目标
关键脚本片段
实战场景
8
文件批量改名
rename s/ /_/g *.png
照片批量去空格
9
日志轮转
mv app.log{,.$(date +%F)}
配合 gzip 压缩
10
文本抽取
awk -F, $3>90{print $1} score.csv
数据筛选
11
sed 批量替换
sed -i s/dev/prod/g *.yaml
环境切换
12
expect 自动交互
expect -c spawn ssh …
免人工输入密码
13
curl + jq
`curl -s api
jq ’.data[]
14
邮件与钉钉告警
sendmail -S smtp… or DingTalk robot
日常监控报警
Week 3 · 体系化
Day
主题与目标
关键脚本片段
实战场景
15
函数与局部变量
function backup() { … }
复用模块化
16
set -euo pipefail
提前终止、空变量检查
生产必备
17
日志封装
log(){ printf "[%s] %s\n" "$(date +%F\ %T)" "$*"; }
统一日志
18
错误捕获
trap echo "line:$LINENO" ERR
精确调试
19
并行 (GNU parallel)
parallel -j 4 ::: *.mp4
多核利用
20
进度条
printf \r[%d%%] $percent
友好输出
21
性能剖析
time ./script.sh、/usr/bin/time -v
优化热点
Week 4 · 生产级
Day
主题与目标
关键脚本片段
实战场景
22
监控 CPU/Mem
`top -bn1
awk ‘/Cpu/{print $2}’`
23
端口存活检查
nc -zvw2 $host $port
服务探针
24
数据库备份
pg_dump -Fc db > db.dump
业务高可用
25
systemd 服务化
ExecStart=/opt/scripts/day25.sh
守护进程
26
CLI 参数解析
使用 getopts/argbash
友好界面
27
YAML/JSON 处理
yq e .items[].metadata.name k8s.yaml
云原生
28
Bash + Python
python - <<PY … PY
混合优势
29
CI/CD 集成
GitHub Actions 调用脚本
自动部署
30
毕业项目
选题示例:“一键巡检并邮件报告”
整合前 29 天全部技能
四、操作步骤示例:Day 10「文本抽取脚本」
#!/usr/bin/env bash
# day10.sh — 统计及格以上学员
set -euo pipefail
INPUT=${1:-score.csv}
awk -F,
NR==1 {next} # 跳过表头
$3 >= 60 {print $1,$3} # 第三列为成绩
"$INPUT" | column -t
运行
chmod +x day10.sh
./day10.sh students.csv
验证
shellcheck day10.sh # 无 Warning
./day10.sh | head # 手动抽样比对
进阶
加选项 -n NUM 仅显示前 N 名输出 Markdown 表格 awk … | printf "|%s|\n"五、如何检验“熟练”到“精通”
阶段
评估维度
合格标准
熟练
代码规范
shellcheck 0 Warning;set -euo pipefail 默认开启
熟练
复用性
常用函数封装到 lib.sh,两个以上脚本共用
精通
健壮性
出错可自愈:重试、日志、通知全链路闭环
精通
性能
大批量任务并发加速不低于单线程 4×
精通
自动化
至少 1 条 CI Pipeline 自动跑静态检查 & 单元测试
六、持续进阶路线
阅读Advanced Bash-Scripting Guidebash Hackers Wiki源码systemd、Kubernetes 脚本工具库社区贡献给开源脚本项目提交 PR编写 Shell 补全(Completion)自动化测试Bats-core 单元测试在 Pull Request 中强制执行七、结语
30 天只是起点。坚持 “每日一脚本、用完即回顾” 的节奏,
三个月 你将从“能写”升到“写得优雅”;
半年 之后,你将可以设计企业级脚本框架,带团队写脚本。
马上行动:
git clone 本计划仓库(自行新建);在 README 打上 Day-1 的 ✅;与同事或朋友互评脚本,持续迭代。下面给出 “今日脚本” —— 一个轻量级、可直接落地的 目录自动备份脚本.
功能点:
把指定目录压缩成带时间戳的 .tar.gz;支持自定义备份保存目录;自动清理 N 天以前的旧备份(默认 7 天);返回 0 表示成功,非 0 表示失败,方便放进 cron。backup_dir.sh
#!/usr/bin/env bash
#
# backup_dir.sh — 目录自动备份并清理旧包
# 用法:
# ./backup_dir.sh -s /path/to/src -d /path/to/dst [-k 14]
# -s 源目录,必填
# -d 备份保存目录,必填
# -k 保留天数,默认 7
# 示例:
# ./backup_dir.sh -s /var/www -d /backup/www -k 30
# 加入 crontab:
# 0 2 * * * /opt/scripts/backup_dir.sh -s /var/www -d /backup/www >> /var/log/backup.log 2>&1
set -euo pipefail
usage() {
echo "Usage: $0 -s <src_dir> -d <dst_dir> [-k <keep_days>]" >&2
exit 1
}
# 默认值
KEEP_DAYS=7
# 解析参数
while getopts ":s:d:k:" opt; do
case $opt in
s) SRC_DIR="${OPTARG}" ;;
d) DST_DIR="${OPTARG}" ;;
k) KEEP_DAYS="${OPTARG}" ;;
*) usage ;;
esac
done
# 参数校验
[[ -z "${SRC_DIR:-}" || -z "${DST_DIR:-}" ]] && usage
[[ ! -d "$SRC_DIR" ]] && { echo "Source dir not found: $SRC_DIR" >&2; exit 2; }
mkdir -p "$DST_DIR"
# 生成文件名
TS=$(date +%Y%m%d_%H%M%S)
BASENAME=$(basename "$SRC_DIR")
ARCHIVE="${DST_DIR}/${BASENAME}_${TS}.tar.gz"
# 备份
echo "$(date +%F %T) Start backup $SRC_DIR -> $ARCHIVE"
tar -czf "$ARCHIVE" -C "$(dirname "$SRC_DIR")" "$BASENAME"
echo "$(date +%F %T) Backup done"
# 清理旧备份
echo "$(date +%F %T) Prune archives older than $KEEP_DAYS days"
find "$DST_DIR" -type f -name "${BASENAME}_*.tar.gz" -mtime +"$KEEP_DAYS" -print -delete
echo "$(date +%F %T) All tasks finished"
一键落地步骤
# 1. 保存脚本
mkdir -p /opt/scripts
nano
/opt/scripts/backup_dir.sh # 或 vim,粘贴上方代码# 2. 赋予可执行权限
chmod +x /opt/scripts/backup_dir.sh
# 3. 手动测试
/opt/scripts/backup_dir.sh -s /etc -d /backup/test
# 4. 接入计划任务 (每日 02:00 备份 /var/www,保留 14 天)
crontab -e
0 2 * * * /opt/scripts/backup_dir.sh -s /var/www -d /backup/www -k 14 >> /var/log/backup_www.log 2>&1
关键知识点回顾
技巧
说明
getopts
原生解析短选项,脚本更通用
set -euo pipefail
当出现错误、未定义变量、管道失败时立即退出
tar -C
先切换目录再打包,避免“目录嵌套”
find … -mtime +N -delete
最简洁的按天数批量删除
$(date +%Y%m%d_%H%M%S)
不含空格的时间戳,方便文件名
加料思路(可作为练习)
邮件 / 钉钉通知:备份结果推送运维群;并发压缩:用 pigz 替代 gzip,多核加速;加密备份:tar 输出管道到 gpg -c;远程同步:备份后通过 rclone 传至对象存储;单元测试:用 Bats-core 验证入参、边界、失败场景。把脚本放进你的每日练功仓库,打上 Day-1 ✅ —— 祝编码顺利!