Linux下用Bash Shell脚本和mysql命令行程序实现带多组参数和标签的MySQL数据库批量数据导出程序

Linux下用Bash Shell脚本连接到MySQL数据库,用SELECT @@secure_file_priv或者SHOW QUERY VARIABLE LIKE 'secure_file_priv'取得secure_file_priv变量的值,值为Linux的目录,如果获取的值为空,则输出提示信息让用户配置my.cnf文件中的secure_file_priv变量的值,否则打印输出这个值,说明输出文件到这个目录,并且实现一个基于多个带标签SQL模板作为配置文件和多组参数的Bash Shell脚本、SELECT INTO OUTFILE语句和mysql命令行程序,实现根据不同的输入参数,自动批量地将MySQL数据库的数据导出为字段用引号包裹以及带逗号分隔的CSV文件和到指定目录上,标签和多个参数(以"_"分割)为组成导出数据文件名,文件已经存在则覆盖原始文件。Bash Shell脚本需要异常处理,输出带时间戳和每个运行批次和每个导出文件作业运行状态的日志文件,每天单独一个带日期的和.log扩展名日志文件,放在logs子目录中,参数全部设置在json配置文件中。

bash 复制代码
#!/bin/bash
set -eo pipefail

# 读取配置文件
CONFIG_FILE="config.json"

# 解析JSON配置
parse_config() {
  jq -r '.database | "\(.host) \(.user) \(.password) \(.database)"' "$CONFIG_FILE" | read host user password database
  template_dir=$(jq -r '.export.template_dir' "$CONFIG_FILE")
  output_dir=$(jq -r '.export.output_dir' "$CONFIG_FILE")
  log_dir=$(jq -r '.logging.log_dir' "$CONFIG_FILE")
  mapfile -t tasks < <(jq -c '.export.tasks[]' "$CONFIG_FILE")
}

# 初始化日志系统
setup_logging() {
  mkdir -p "$log_dir"
  log_file="${log_dir}/$(date +%Y%m%d).log"
  touch "$log_file"
}

# 日志记录函数
log() {
  local status=$1
  local message=$2
  echo "[$(date '+%Y-%m-%d %T')] [${current_task}] [${status}] ${message}" >> "$log_file"
}

# 检查secure_file_priv配置
check_secure_file_priv() {
  local secure_file_priv=$(mysql -h"$host" -u"$user" -p"$password" -sN -e "SELECT @@secure_file_priv;")
  
  if [[ -z "$secure_file_priv" || "$secure_file_priv" == "NULL" ]]; then
    log "ERROR" "secure_file_priv未配置,请修改my.cnf文件"
    exit 1
  else
    log "INFO" "secure_file_priv配置为:${secure_file_priv}"
    if [[ ! "$output_dir" =~ ^$secure_file_priv ]]; then
      log "ERROR" "输出目录必须在secure_file_priv路径下"
      exit 1
    fi
  fi
}

# 执行数据导出
export_data() {
  local label=$1
  local params=(${2//_/ })
  local template_file="${template_dir}/${label}.sql"
  local output_file="${output_dir}/${label}_${2}.csv"

  # 处理SQL模板
  if [[ ! -f "$template_file" ]]; then
    log "ERROR" "模板文件不存在:${template_file}"
    return 1
  fi

  # 替换模板参数
  sql_query=$(<"$template_file")
  for i in "${!params[@]}"; do
    param_name="param$((i+1))"
    param_value="${params[$i]//\'/\\\'}"
    sql_query=${sql_query//\{\{${param_name}\}\}/${param_value}}
  done

  # 构建完整SQL语句
  sql_query+=" INTO OUTFILE '${output_file}' 
              FIELDS TERMINATED BY ',' 
              ENCLOSED BY '\"' 
              ESCAPED BY '\"' 
              LINES TERMINATED BY '\\n'"

  # 执行导出
  log "INFO" "开始导出:${output_file}"
  if mysql -h"$host" -u"$user" -p"$password" -D"$database" -e "$sql_query" 2>> "$log_file"; then
    log "SUCCESS" "导出成功"
  else
    log "ERROR" "导出失败"
    return 1
  fi
}

# 主执行流程
main() {
  parse_config
  setup_logging
  check_secure_file_priv
  mkdir -p "$output_dir"

  for task in "${tasks[@]}"; do
    label=$(jq -r '.label' <<< "$task")
    mapfile -t params_list < <(jq -cr '.params[] | join("_")' <<< "$task")
    
    for params in "${params_list[@]}"; do
      current_task="${label}_${params}"
      log "INFO" "开始处理任务"
      
      if export_data "$label" "$params"; then
        log "INFO" "任务处理完成"
      else
        log "ERROR" "任务处理失败"
      fi
    done
  done
}

main

配套的config.json示例:

json 复制代码
{
  "database": {
    "host": "localhost",
    "user": "root",
    "password": "your_password",
    "database": "test_db"
  },
  "export": {
    "template_dir": "./sql_templates",
    "output_dir": "/var/lib/mysql-files/exports",
    "tasks": [
      {
        "label": "users",
        "params": [
          ["active", "2023"],
          ["inactive", "2022"]
        ]
      },
      {
        "label": "orders",
        "params": [
          ["pending"],
          ["completed"]
        ]
      }
    ]
  },
  "logging": {
    "log_dir": "./logs",
    "log_level": "INFO"
  }
}

SQL模板示例(sql_templates/users.sql):

sql 复制代码
SELECT * 
FROM users 
WHERE status = '{{param1}}'
AND YEAR(created_at) = '{{param2}}'

脚本特点:

  1. 安全验证:自动检查MySQL的secure_file_priv配置
  2. 模板引擎:支持带{{param}}占位符的SQL模板
  3. 批量处理:支持多任务多参数批量执行
  4. 日志系统
    • 每天生成独立日志文件
    • 包含时间戳和任务状态
    • 自动创建日志目录
  5. 错误处理
    • 自动捕获并记录错误
    • 模板文件存在性检查
    • MySQL执行错误处理
  6. 文件管理
    • 自动创建输出目录
    • 文件名自动生成(标签_参数1_参数2.csv)
    • 自动覆盖已有文件

使用说明:

  1. 将配置文件保存为config.json
  2. 创建sql_templates目录并放置SQL模板文件
  3. 确保MySQL用户有FILE权限和目标目录写入权限
  4. 通过chmod +x script.sh添加执行权限
  5. 使用./script.sh执行脚本

注意事项:

  1. MySQL的secure_file_priv目录需要提前配置
  2. 确保JSON配置文件的语法正确
  3. SQL模板中的参数占位符使用双大括号格式{{param}}
  4. 输出目录必须位于secure_file_priv指定的路径下
  5. 建议在生产环境中使用配置文件权限限制(如chmod 600 config.json)
相关推荐
前端码虫25 分钟前
JS分支和循环
开发语言·前端·javascript
惜.己25 分钟前
MySql(十)
数据库·mysql
GISer_Jing27 分钟前
MonitorSDK_性能监控(从Web Vital性能指标、PerformanceObserver API和具体代码实现)
开发语言·前端·javascript
岸边的风34 分钟前
JavaScript篇:JS事件冒泡:别让点击事件‘传染’!
开发语言·前端·javascript
瓯雅爱分享2 小时前
MES管理系统:Java+Vue,含源码与文档,实现生产过程实时监控、调度与优化,提升制造企业效能
java·mysql·vue·软件工程·源代码管理
bubiyoushang8882 小时前
matlab雷达定位仿真
开发语言·matlab
yezipi耶不耶3 小时前
Rust入门之并发编程基础(一)
开发语言·后端·rust
lichenyang4533 小时前
使用react进行用户管理系统
数据库
木子.李3473 小时前
数据结构-算法学习C++(入门)
数据库·c++·学习·算法
Layux4 小时前
flowable候选人及候选人组(Candidate Users 、Candidate Groups)的应用包含拾取、归还、交接
java·数据库