Files
nexus/openclaw/xingyao/scripts/safe-edit.sh
2026-03-23 20:57:45 +08:00

262 lines
6.5 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# 安全文件编辑脚本
# 基于2026-03-13文件编辑失败的经验教训
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 显示帮助信息
show_help() {
echo "🔧 安全文件编辑脚本"
echo "======================"
echo "用法: $0 <文件路径> <旧文本> <新文本>"
echo ""
echo "选项:"
echo " -h, --help 显示帮助信息"
echo " -v, --verbose 详细模式"
echo " -b, --backup 保留备份文件(默认编辑成功后删除)"
echo " -f, --force 强制编辑(不检查匹配次数)"
echo ""
echo "示例:"
echo " $0 config.yaml 'port: 8080' 'port: 9090'"
echo " $0 --verbose README.md '旧版本' '新版本'"
echo ""
echo "安全特性:"
echo " • 自动备份原文件"
echo " • 验证文本匹配"
echo " • 失败时自动恢复"
echo " • 编辑日志记录"
}
# 初始化变量
VERBOSE=0
KEEP_BACKUP=0
FORCE=0
FILE=""
OLD_TEXT=""
NEW_TEXT=""
# 解析参数
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_help
exit 0
;;
-v|--verbose)
VERBOSE=1
shift
;;
-b|--backup)
KEEP_BACKUP=1
shift
;;
-f|--force)
FORCE=1
shift
;;
*)
if [ -z "$FILE" ]; then
FILE="$1"
elif [ -z "$OLD_TEXT" ]; then
OLD_TEXT="$1"
elif [ -z "$NEW_TEXT" ]; then
NEW_TEXT="$1"
else
echo -e "${RED}错误:参数过多${NC}"
show_help
exit 1
fi
shift
;;
esac
done
# 检查必要参数
if [ -z "$FILE" ] || [ -z "$OLD_TEXT" ] || [ -z "$NEW_TEXT" ]; then
echo -e "${RED}错误:缺少必要参数${NC}"
show_help
exit 1
fi
# 检查文件是否存在
if [ ! -f "$FILE" ]; then
echo -e "${RED}错误:文件不存在: $FILE${NC}"
exit 1
fi
# 详细模式输出
log() {
if [ $VERBOSE -eq 1 ]; then
echo -e "${BLUE}[INFO]${NC} $1"
fi
}
error() {
echo -e "${RED}[ERROR]${NC} $1"
}
success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
# 主函数
main() {
echo "🔧 开始安全文件编辑"
echo "======================"
echo "文件: $FILE"
echo "旧文本: \"$OLD_TEXT\""
echo "新文本: \"$NEW_TEXT\""
echo ""
# 步骤1备份原文件
BACKUP_FILE="${FILE}.backup.$(date +%Y%m%d_%H%M%S)"
log "创建备份: $BACKUP_FILE"
cp "$FILE" "$BACKUP_FILE"
if [ $? -ne 0 ]; then
error "备份失败"
exit 1
fi
# 步骤2检查文件权限
PERMISSIONS=$(stat -f "%Sp" "$FILE")
log "文件权限: $PERMISSIONS"
# 步骤3验证文本匹配
log "验证文本匹配..."
# 检查匹配次数
MATCH_COUNT=$(grep -c "$OLD_TEXT" "$FILE")
log "找到 $MATCH_COUNT 处匹配"
if [ $MATCH_COUNT -eq 0 ]; then
error "未找到匹配文本"
echo "建议:"
echo " 1. 检查文本是否完全匹配(包括空格和换行符)"
echo " 2. 使用 cat -A 查看文件特殊字符"
echo " 3. 考虑使用 write 工具重新创建文件"
if [ $FORCE -eq 0 ]; then
# 恢复备份
log "恢复备份文件"
cp "$BACKUP_FILE" "$FILE"
exit 1
else
warning "强制模式:继续编辑"
fi
elif [ $MATCH_COUNT -gt 1 ] && [ $FORCE -eq 0 ]; then
warning "找到 $MATCH_COUNT 处匹配,可能不精确"
echo "匹配位置:"
grep -n "$OLD_TEXT" "$FILE"
echo ""
echo "建议:"
echo " 1. 使用更精确的匹配文本"
echo " 2. 使用 -f 参数强制编辑"
echo " 3. 或手动编辑文件"
# 恢复备份
log "恢复备份文件"
cp "$BACKUP_FILE" "$FILE"
exit 1
fi
# 步骤4显示匹配上下文
if [ $VERBOSE -eq 1 ]; then
echo "匹配上下文:"
grep -A2 -B2 "$OLD_TEXT" "$FILE" | cat -A
echo ""
fi
# 步骤5执行编辑
log "执行编辑操作..."
edit "$FILE" "$OLD_TEXT" "$NEW_TEXT"
if [ $? -ne 0 ]; then
error "编辑失败"
log "恢复备份文件"
cp "$BACKUP_FILE" "$FILE"
exit 1
fi
# 步骤6验证编辑结果
log "验证编辑结果..."
# 检查新文本是否存在
NEW_COUNT=$(grep -c "$NEW_TEXT" "$FILE")
if [ $NEW_COUNT -eq 0 ]; then
error "新文本未找到,编辑可能失败"
log "恢复备份文件"
cp "$BACKUP_FILE" "$FILE"
exit 1
fi
# 检查旧文本是否还存在
OLD_COUNT=$(grep -c "$OLD_TEXT" "$FILE")
if [ $OLD_COUNT -gt 0 ]; then
warning "仍有 $OLD_COUNT 处旧文本存在"
fi
# 步骤7文件完整性检查
log "检查文件完整性..."
# 检查文件大小
ORIG_SIZE=$(stat -f%z "$BACKUP_FILE")
NEW_SIZE=$(stat -f%z "$FILE")
log "原始大小: $ORIG_SIZE 字节"
log "新大小: $NEW_SIZE 字节"
if [ $NEW_SIZE -eq 0 ]; then
error "文件大小为0编辑可能损坏了文件"
log "恢复备份文件"
cp "$BACKUP_FILE" "$FILE"
exit 1
fi
# 步骤8清理和记录
if [ $KEEP_BACKUP -eq 0 ]; then
log "删除备份文件"
rm "$BACKUP_FILE"
else
log "保留备份文件: $BACKUP_FILE"
fi
# 记录编辑日志
LOG_FILE="$HOME/.openclaw/workspace/managed-systems/logs/edit-log.md"
mkdir -p "$(dirname "$LOG_FILE")"
echo "## $(date '+%Y-%m-%d %H:%M:%S')" >> "$LOG_FILE"
echo "- **文件**: $FILE" >> "$LOG_FILE"
echo "- **操作**: 替换文本" >> "$LOG_FILE"
echo "- **匹配数**: $MATCH_COUNT" >> "$LOG_FILE"
echo "- **结果**: 成功" >> "$LOG_FILE"
echo "" >> "$LOG_FILE"
# 步骤9完成
success "编辑成功完成"
echo ""
echo "📊 编辑统计:"
echo " • 匹配位置: $MATCH_COUNT"
echo " • 新文本出现: $NEW_COUNT"
echo " • 文件大小变化: $ORIG_SIZE$NEW_SIZE 字节"
if [ $KEEP_BACKUP -eq 1 ]; then
echo " • 备份文件: $BACKUP_FILE"
fi
echo ""
echo "✅ 安全编辑流程完成"
}
# 运行主函数
main "$@"