#!/bin/bash # ============================================================================= # Neo4j同步程序运行脚本 # 适用于Linux生产环境 # ============================================================================= # 脚本配置 SCRIPT_NAME="run_parse_neo4j.sh" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$SCRIPT_DIR" PYTHON_SCRIPT="$PROJECT_ROOT/app/core/data_parse/parse_neo4j_process.py" LOG_DIR="$PROJECT_ROOT/logs" LOG_FILE="$LOG_DIR/parse_neo4j_$(date +%Y%m%d_%H%M%S).log" PID_FILE="$PROJECT_ROOT/parse_neo4j.pid" LOCK_FILE="$PROJECT_ROOT/parse_neo4j.lock" # 环境变量 export PYTHONPATH="$PROJECT_ROOT:$PYTHONPATH" export PYTHONUNBUFFERED=1 # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # 日志函数 log_info() { echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] [INFO]${NC} $1" | tee -a "$LOG_FILE" } log_warn() { echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] [WARN]${NC} $1" | tee -a "$LOG_FILE" } log_error() { echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] [ERROR]${NC} $1" | tee -a "$LOG_FILE" } log_debug() { echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')] [DEBUG]${NC} $1" | tee -a "$LOG_FILE" } # 清理函数 cleanup() { log_info "执行清理操作..." # 删除PID文件 if [ -f "$PID_FILE" ]; then rm -f "$PID_FILE" log_info "已删除PID文件: $PID_FILE" fi # 删除锁文件 if [ -f "$LOCK_FILE" ]; then rm -f "$LOCK_FILE" log_info "已删除锁文件: $LOCK_FILE" fi log_info "清理操作完成" } # 信号处理 trap cleanup EXIT trap 'log_error "收到中断信号,正在退出..."; exit 1' INT TERM # 检查依赖 check_dependencies() { log_info "检查系统依赖..." # 检查Python if ! command -v python3 &> /dev/null; then log_error "Python3 未安装或不在PATH中" return 1 fi PYTHON_VERSION=$(python3 --version 2>&1) log_info "Python版本: $PYTHON_VERSION" # 检查pip if ! command -v pip3 &> /dev/null; then log_error "pip3 未安装或不在PATH中" return 1 fi # 检查虚拟环境(如果存在) if [ -d "$PROJECT_ROOT/venv" ]; then log_info "检测到虚拟环境: $PROJECT_ROOT/venv" source "$PROJECT_ROOT/venv/bin/activate" log_info "已激活虚拟环境" fi return 0 } # 检查Python包依赖 check_python_packages() { log_info "检查Python包依赖..." local required_packages=( "psycopg2-binary" "neo4j" "openai" "boto3" "Pillow" "pytesseract" "requests" ) for package in "${required_packages[@]}"; do if ! python3 -c "import ${package//-/_}" 2>/dev/null; then log_warn "Python包未安装: $package" if [ "$1" = "--install" ]; then log_info "尝试安装包: $package" pip3 install "$package" || log_error "安装包失败: $package" fi else log_debug "Python包已安装: $package" fi done } # 创建日志目录 create_log_dir() { if [ ! -d "$LOG_DIR" ]; then mkdir -p "$LOG_DIR" log_info "创建日志目录: $LOG_DIR" fi } # 检查是否已在运行 check_running() { if [ -f "$PID_FILE" ]; then local pid=$(cat "$PID_FILE") if ps -p "$pid" > /dev/null 2>&1; then log_error "程序已在运行,PID: $pid" return 1 else log_warn "发现过期的PID文件,正在清理..." rm -f "$PID_FILE" fi fi if [ -f "$LOCK_FILE" ]; then log_error "发现锁文件,可能程序正在运行或上次异常退出" return 1 fi return 0 } # 创建锁文件 create_lock() { echo "$$" > "$LOCK_FILE" echo "$$" > "$PID_FILE" log_info "创建锁文件和PID文件" } # 检查数据库连接 check_database_connection() { log_info "检查数据库连接..." # 这里可以添加数据库连接检查逻辑 # 例如:检查PostgreSQL和Neo4j是否可访问 log_info "数据库连接检查完成" } # 运行主程序 run_main_program() { log_info "开始运行Neo4j同步程序..." log_info "工作目录: $PROJECT_ROOT" log_info "Python脚本: $PYTHON_SCRIPT" log_info "日志文件: $LOG_FILE" # 运行Python脚本 cd "$PROJECT_ROOT" python3 "$PYTHON_SCRIPT" 2>&1 | tee -a "$LOG_FILE" local exit_code=$? if [ $exit_code -eq 0 ]; then log_info "程序执行成功" else log_error "程序执行失败,退出码: $exit_code" fi return $exit_code } # 显示帮助信息 show_help() { echo "用法: $0 [选项]" echo "" echo "选项:" echo " -h, --help 显示此帮助信息" echo " -v, --version 显示版本信息" echo " -i, --install 自动安装缺失的Python包" echo " -c, --check 只检查依赖,不运行程序" echo " -f, --force 强制运行(忽略锁文件检查)" echo " -l, --log-dir DIR 指定日志目录" echo "" echo "示例:" echo " $0 正常运行程序" echo " $0 --install 安装依赖后运行程序" echo " $0 --check 只检查依赖" echo " $0 --force 强制运行程序" } # 显示版本信息 show_version() { echo "Neo4j同步程序运行脚本 v1.0.0" echo "适用于Linux生产环境" } # 主函数 main() { local force_run=false local check_only=false local install_packages=false # 解析命令行参数 while [[ $# -gt 0 ]]; do case $1 in -h|--help) show_help exit 0 ;; -v|--version) show_version exit 0 ;; -i|--install) install_packages=true shift ;; -c|--check) check_only=true shift ;; -f|--force) force_run=true shift ;; -l|--log-dir) LOG_DIR="$2" shift 2 ;; *) log_error "未知参数: $1" show_help exit 1 ;; esac done # 创建日志目录 create_log_dir # 记录脚本启动 log_info "==========================================" log_info "Neo4j同步程序运行脚本启动" log_info "脚本路径: $0" log_info "启动时间: $(date)" log_info "==========================================" # 检查依赖 if ! check_dependencies; then log_error "依赖检查失败,程序退出" exit 1 fi # 检查Python包 check_python_packages $([ "$install_packages" = true ] && echo "--install") # 如果只是检查依赖,则退出 if [ "$check_only" = true ]; then log_info "依赖检查完成,程序退出" exit 0 fi # 检查是否已在运行 if [ "$force_run" = false ] && ! check_running; then log_error "程序已在运行或存在锁文件,程序退出" exit 1 fi # 创建锁文件 create_lock # 检查数据库连接 check_database_connection # 运行主程序 if run_main_program; then log_info "程序执行完成" exit 0 else log_error "程序执行失败" exit 1 fi } # 脚本入口点 if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then main "$@" fi