适读人群:对 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=$' |
|
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 |
统一日志 |
|
18 |
错误捕获 |
trap 'echo “line:$LINENO”' ERR |
准确调试 |
|
19 |
并行 (GNU parallel) |
parallel -j 4 ::: *.mp4 |
多核利用 |
|
20 |
进度条 |
printf ' |
友善输出 |
|
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|
“
五、如何检验“熟练”到“精通”
|
阶段 |
评估维度 |
合格标准 |
|
熟练 |
代码规范 |
shellcheck 0 Warning;set -euo pipefail 默认开启 |
|
熟练 |
复用性 |
常用函数封装到 lib.sh,两个以上脚本共用 |
|
精通 |
健壮性 |
出错可自愈:重试、日志、通知全链路闭环 |
|
精通 |
性能 |
大批量任务并发加速不低于单线程 4× |
|
精通 |
自动化 |
至少 1 条 CI Pipeline 自动跑静态检查 & 单元测试 |
六、持续进阶路线
- 阅读
- Advanced Bash-Scripting Guide
- bash 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 ✅ —— 祝编码顺利!



收藏了,感谢分享