com um clique
shell-scripting-safe
写 shell/bash 脚本时使用。防止静默失败与误删。
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Menu
写 shell/bash 脚本时使用。防止静默失败与误删。
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Baseado na classificação ocupacional SOC
做 Cocos Creator 多机型/多分辨率适配时使用。Canvas、Widget、安全区。
Cocos Creator 用 AssetBundle 做分包/远程资源时使用。加载、释放、依赖、缓存。
优化 Cocos Creator 渲染性能时使用。合批、图集、动静分离、Label。
给 Cocos Creator 原生包做热更新时使用。version manifest、增量、校验、回滚。
写 Cocos Creator 动效/动画时使用。tween、Animation、Spine、性能与清理。
做 Cocos Creator 大量条目列表时使用。虚拟列表、节点复用。
| name | shell-scripting-safe |
| description | 写 shell/bash 脚本时使用。防止静默失败与误删。 |
| category | devops |
| tags | ["shell","bash","脚本"] |
.sh / bash 脚本。set -euo pipefail,让错误立即暴露规则: 每个脚本第一行(shebang 之后)加 set -euo pipefail,确保命令非零退出立即终止脚本(-e),引用未定义变量报错(-u),管道中间命令失败也能被捕获(-o pipefail)。
为什么: AI 生成的 bash 脚本默认不加这三个选项,导致静默失败危害极大。曾见真实事故:TARGET_DIR="" 变量赋值失败(来自上一条命令出错),下一步 rm -rf "$TARGET_DIR/" 展开为 rm -rf "/" 并成功执行——因为没有 -u,空变量不报错;因为没有 -e,上一步出错没停下来。加上这三行,相同场景会在变量赋值处立即报错退出。
怎么做:
#!/usr/bin/env bash
set -euo pipefail
# 之后的所有命令:任何一步失败即停止,未定义变量即报错
command || true 或 command || echo "可选步骤失败,继续" 显式豁免,不要关掉全局 -e。set 选项。规则: 引用任何变量时都用双引号:"$var"、"$@"、"${array[@]}";只在明确需要分词或通配符展开时才省略引号。
为什么: AI 写 bash 时很少给变量加引号,遇到含空格或通配符的路径时立刻出事。典型案例:cp $SRC $DST 在 SRC="/home/user/my files/data.txt" 时被 shell 解析为 cp /home/user/my files/data.txt $DST,变成三个参数,cp 报错或拷错文件。更危险的是 rm -rf $DIR/*,若 DIR 是 /tmp/app (带尾随空格),展开结果不可预料。
怎么做:
# 反例
cp $SRC $DST
rm -rf $DIR/*
# 正例
cp "$SRC" "$DST"
rm -rf "${DIR:?}/"* # :? 额外保证变量非空,空则报错退出
"${arr[@]}" 而非 ${arr[*]},保留每个元素的边界。output="$(some_command)"。规则: 执行 rm -rf、dd、mkfs、大范围覆盖等不可逆操作前,必须:① 用 ${VAR:?错误信息} 或显式 if [ -z "$VAR" ] 校验关键变量非空,② 检查路径符合预期(不是根目录、不是系统目录),③ 支持 DRY_RUN=1 模式只打印不执行。
为什么: AI 生成的清理脚本几乎从不做这类防御,使用者一旦环境变量配置错误,rm -rf "$DEPLOY_DIR/" 就会变成 rm -rf "/" 或 rm -rf "/var/" 并实际执行。这类事故在运维历史上反复出现,恢复成本极高。
怎么做:
#!/usr/bin/env bash
set -euo pipefail
DEPLOY_DIR="${DEPLOY_DIR:?必须设置 DEPLOY_DIR 环境变量}"
DRY_RUN="${DRY_RUN:-0}"
# 路径安全检查
if [[ "$DEPLOY_DIR" == "/" || "$DEPLOY_DIR" == "/usr" || "$DEPLOY_DIR" == "/etc" ]]; then
echo "❌ DEPLOY_DIR 疑似系统目录,拒绝执行" >&2
exit 1
fi
do_rm() {
if [[ "$DRY_RUN" == "1" ]]; then
echo "[DRY_RUN] rm -rf $1"
else
rm -rf "$1"
fi
}
do_rm "${DEPLOY_DIR}/old_release"
规则: 依赖外部命令前检查其是否存在(command -v);关键步骤打印清晰日志;捕获并展示有意义的错误信息,不让失败静默消失。
为什么: AI 生成的脚本常假设 jq、aws、kubectl 等工具已安装,在开发机上跑通了,在干净的 CI 容器或另一台服务器上立刻失败,且因为没有检查,报错信息是"command not found"而非"请先安装 jq"。加上静默管道失败(无 pipefail),真正的出错行往往被淹没。
怎么做:
#!/usr/bin/env bash
set -euo pipefail
# 前置依赖检查
for cmd in jq aws curl; do
if ! command -v "$cmd" &>/dev/null; then
echo "❌ 缺少依赖:$cmd,请先安装" >&2
exit 1
fi
done
# 关键步骤带日志
echo "🔄 开始上传到 S3..."
aws s3 sync ./dist "s3://${BUCKET_NAME}/" \
|| { echo "❌ S3 上传失败,退出码:$?" >&2; exit 1; }
echo "✅ 上传完成"
trap 'echo "脚本在第 $LINENO 行意外退出"' ERR 输出出错行号,方便定位。规则: 超过 50 行的脚本用函数组织,每个函数只做一件事;脚本入口校验参数数量和格式;业务逻辑复杂(JSON 处理、并发、错误恢复)时考虑改用 Python/Go,不要用 bash 硬扛。
为什么: AI 生成的长 bash 脚本常常是一整个线性流,几百行没有任何函数,全局变量满天飞,出错后根本无从定位。更隐蔽的问题:bash 的字符串处理、算术、数组在边界情况下行为出人意料,AI 很少把这些坑写进脚本注释,维护者往往在生产事故后才发现。
怎么做:
#!/usr/bin/env bash
set -euo pipefail
usage() {
echo "用法: $0 <环境> <版本>" >&2
echo " 环境: staging | production" >&2
exit 1
}
# 参数校验
[[ $# -eq 2 ]] || usage
ENV="$1"
VERSION="$2"
[[ "$ENV" =~ ^(staging|production)$ ]] || { echo "❌ 无效环境: $ENV" >&2; usage; }
deploy() {
local env="$1" version="$2"
echo "部署 $version 到 $env..."
# ... 具体逻辑
}
deploy "$ENV" "$VERSION"
jq,不用 grep/sed 手撕;更复杂的改用 Python。#!/bin/bash
# 反例:没有 set -euo pipefail
TARGET=$1 # ❌ 无引号,无参数校验
BACKUP_DIR=/tmp/backup
mkdir $BACKUP_DIR
cp -r $TARGET $BACKUP_DIR # ❌ 路径含空格时出错
rm -rf $TARGET # ❌ TARGET 为空则 rm -rf ""(行为未定义)
echo "done" # 即使前面出错也会打印
#!/usr/bin/env bash
set -euo pipefail
trap 'echo "脚本在第 $LINENO 行意外退出" >&2' ERR
usage() { echo "用法: $0 <目标目录>" >&2; exit 1; }
[[ $# -eq 1 ]] || usage
TARGET="${1:?目标目录不能为空}" # ✅ 非空校验
DRY_RUN="${DRY_RUN:-0}"
BACKUP_DIR="/tmp/backup_$(date +%Y%m%d%H%M%S)"
# 路径合法性检查
[[ -d "$TARGET" ]] || { echo "❌ 目标目录不存在: $TARGET" >&2; exit 1; }
echo "备份目录: $BACKUP_DIR"
mkdir -p "$BACKUP_DIR" # ✅ 变量加引号
cp -r "$TARGET" "$BACKUP_DIR/" # ✅
if [[ "$DRY_RUN" == "1" ]]; then
echo "[DRY_RUN] 不执行 rm,目标: $TARGET" # ✅ dry-run 保护
else
rm -rf "$TARGET"
fi
echo "完成"
set -euo pipefail(shebang 紧接其后)。"$var"),数组用 "${arr[@]}"。${VAR:?})和路径合法性检查。DRY_RUN 模式,或在危险步骤前有显式确认提示。command -v 提前检查,缺失时给出明确提示。