第01章:AI帮我写Shell脚本,但它差点把服务器数据删了

第01章:AI帮我写Shell脚本,但它差点把服务器数据删了

“AI 写 Shell 脚本的速度很快,但 Shell 命令的破坏性也很快——而且往往不可逆。”


ℹ️ 版本说明:本章基于 Ubuntu 26.04 LTS(Noble)、Bash 5.2+

1.1 AI默认会生成什么

你让 AI 帮你写一个"清理30天前的日志文件"的脚本:

#!/bin/bash
# 清理30天前的日志文件
LOG_DIR="/var/log/myapp"
find $LOG_DIR -name "*.log" -mtime +30 -exec rm -f {} \;
echo "清理完成"

这个脚本在大多数情况下能正常工作。但在以下几种场景下,它会成为一场灾难:

  • $LOG_DIR 变量为空时:命令变成 find -name "*.log" → 从当前目录开始搜索,或者更糟,find / -name "*.log" -mtime +30 -exec rm -f {} \; → 删遍全盘
  • 日志目录包含软链接时:rm -f 可能删除链接指向的原始文件
  • 脚本以 root 身份运行时,任何路径错误都会产生系统级破坏

AI 不会告诉你这些,因为它不知道这个脚本会在什么环境下运行,以什么权限运行,变量是否可能为空。


1.2 AI通常遗漏的5个坑

⚠️ 坑1:变量未加引号导致路径展开错误

# 危险:变量未加引号
find $LOG_DIR -name "*.log" -delete

# 如果 LOG_DIR="/path/with spaces" → find /path/with spaces 会出错
# 如果 LOG_DIR="" → find  -name "*.log" -delete → 删当前目录

修复:所有变量都要加双引号:"$LOG_DIR"


⚠️ 坑2:没有检查变量是否为空

# 在 rm -rf 前没有检查变量
rm -rf "$TEMP_DIR"/*  # 如果 TEMP_DIR="" 或未设置,这是 rm -rf /*

这是 Shell 脚本最经典的灾难——rm -rf $DIR/ 其中 $DIR 为空,等价于 rm -rf /


⚠️ 坑3:没有 set -euo pipefail

AI 生成的脚本通常没有错误处理:

#!/bin/bash
mkdir /data/backup
cp -r /data/production/* /data/backup/  # 如果 cp 失败,脚本继续执行
rm -rf /data/production/*               # 备份失败但数据被删除了!

修复:脚本开头加上:

set -euo pipefail
# -e:任何命令失败就退出
# -u:使用未定义变量就退出
# -o pipefail:管道中任何命令失败都报错

⚠️ 坑4:调试模式没用上

AI 生成的脚本通常没有调试支持。在生产环境,当脚本出问题时,你不知道哪一行失败了,也不知道变量的实际值是什么。

修复:在脚本里加入可选的调试模式:

[[ "${DEBUG:-0}" == "1" ]] && set -x  # DEBUG=1 ./script.sh 开启调试

⚠️ 坑5:没有演习模式(Dry Run)

破坏性操作(删除文件、覆盖配置)在执行前应该先告诉你"我将要做什么",而不是直接执行。

AI 生成的脚本通常没有 --dry-run 选项,你必须在生产环境上直接"赌"这个脚本是对的。


1.3 更好的提示词

提示词 P01:写一个生产安全的文件清理脚本

使用时机:需要定期清理日志、临时文件等

比默认多了什么

  • set -euo pipefail
  • 变量空值检查
  • dry-run 模式
  • 操作日志
帮我写一个生产安全的 Bash 脚本,清理指定目录下30天前的日志文件。

安全要求:
1. 脚本头部使用 set -euo pipefail
2. 对所有目录变量进行非空检查:如果目录变量为空或目录不存在,立即退出并报错
3. 支持 --dry-run 参数:只打印将要删除的文件,不实际删除
4. 删除前先 df -h 显示磁盘使用情况,删除后再显示一次(验证效果)
5. 所有变量使用双引号 "$VAR"
6. 脚本自身产生日志:操作记录到 /var/log/cleanup-YYYYMMDD.log

使用方式:
./cleanup.sh --dry-run                    # 演习,不实际删除
./cleanup.sh                              # 实际执行
LOG_DIR=/var/log/myapp ./cleanup.sh      # 指定目录

基于 Ubuntu 26.04 LTS + Bash 5.2。

提示词 P02:为 AI 生成的 Shell 脚本做安全审计

使用时机:你有一段 AI 生成的 Shell 脚本,想在执行前检查安全性

比默认多了什么

  • 系统化的危险模式检查
  • 具体的修复方案
请审查以下 Bash 脚本的安全性,重点检查:

[粘贴你的脚本]

检查清单:
1. 是否有 set -euo pipefail?如果没有,指出哪些命令失败了会导致问题
2. 所有变量(特别是路径变量)是否加了双引号?列出所有危险的展开
3. 是否有任何可能破坏性的命令(rm、mv、chmod 777、dd)在没有检查前提条件的情况下执行?
4. 变量是否有空值保护?特别是 rm -rf "$VAR"/ 这类模式
5. 是否有超时保护(对于调用外部命令)?

对每个发现的问题:
- 指出具体的行号
- 说明最坏情况下会发生什么
- 给出修复后的代码

基于 Ubuntu 26.04 LTS + Bash 5.2。

提示词 P03:Shell 脚本的测试和文档模板

使用时机:写需要长期维护的 Shell 脚本(crontab 自动运行、运维操作脚本)

比默认多了什么

  • 脚本帮助信息(-h 参数)
  • 参数解析
  • 测试验证步骤
帮我写一个完整的、可维护的 Shell 脚本模板,功能是:[你的功能描述]。

模板要包含:
1. 脚本头部注释:用途、使用方法、作者、版本
2. set -euo pipefail
3. 参数解析:支持 -h(帮助)、--dry-run(演习)、-v(详细输出)
4. 颜色输出函数:info(绿色)、warn(黄色)、error(红色)
5. 清理函数:脚本退出时(无论成功还是失败)执行 cleanup
6. 日志函数:带时间戳的日志输出

同时,告诉我如何用 shellcheck 检查这个脚本的语法和安全问题:
- 安装命令(Ubuntu 26.04)
- 检查命令
- 最常见的 shellcheck 警告及含义

基于 Ubuntu 26.04 LTS + Bash 5.2。

1.4 验收清单

检查项 验证方法 AI辅助
有 set -euo pipefail head -5 script.sh 让 AI 添加到脚本开头
所有变量有双引号 shellcheck script.sh 让 AI 修复 SC2086 警告
破坏性操作前有前提检查 代码审查 rm/mv 前的 if 语句 让 AI 添加非空和路径检查
有 dry-run 支持 ./script.sh --dry-run 不实际执行 让 AI 添加 dry-run 参数
shellcheck 无错误 shellcheck -S error script.sh 让 AI 修复所有 SC 报警
有操作日志 执行后 /var/log/ 有记录 让 AI 添加日志函数

1.5 本章小结

如果你只记一件事:在任何 AI 生成的 Shell 脚本里,第一行(shebang 后面)加上 set -euo pipefail,这三个参数能防止 70% 的脚本灾难。

Shell 脚本安全的三个习惯

  1. 先演习,再执行:任何破坏性脚本都应该有 --dry-run 模式,先跑一遍看它要做什么
  2. 让 shellcheck 检查:不要相信"能运行"等于"是安全的",shellcheck 会发现你和 AI 都没注意到的问题
  3. 变量加引号是本能:不是代码风格,是安全需要——"$VAR"$VAR 的区别在变量为空时就是数据丢失和正常运行的区别

→ 第2章:AI配置的SSH,为什么不安全?