1 #!/bin/bash 2 3 # ############################################################################# 4 # 5 # 功能: 使用 mongoexport 导出 MongoDB。支持指定库、表、认证信息和输出路径。 6 # 7 # 使用方法: ./export_mongo.sh -d <db_name> [选项] 8 # 通过 ./export_mongo.sh -h 查看所有选项。 9 # 10 # ############################################################################# 11 12 # --- 默认配置 --- 13 HOST="localhost" 14 PORT="27017" 15 AUTH_DB="admin" # 用于认证的数据库 16 17 # --- 函数定义 --- 18 19 # 显示用法说明 20 usage() { 21 cat <<EOF 22 使用方法: $0 -d <数据库名> [选项] 23 24 这是一个用于导出 MongoDB 数据的多功能脚本。 25 26 必须参数: 27 -d <数据库名> 要导出的数据库名称。 28 29 可选参数: 30 -c <集合名> 要导出的集合名称。如果省略,则导出指定数据库中的所有集合。 31 -o <输出路径> 指定保存导出文件的目录。如果省略,将自动创建一个带时间戳的目录。 32 -u <用户名> 用于数据库认证的用户名。 33 -p <密码> 用于数据库认证的密码。 34 -h 显示此帮助信息。 35 36 示例: 37 # 1. 显示帮助信息 38 $0 -h 39 40 # 2. 导出单个集合到自动生成的目录 41 $0 -d my_app_db -c users 42 43 # 3. 导出单个集合到指定目录 (带认证) 44 $0 -d my_app_db -c users -u admin -p 's3cr3t' -o /mnt/mongo_backups 45 46 # 4. 导出整个数据库到指定目录 47 $0 -d my_app_db -o /tmp/db_full_export 48 49 # 5. 导出整个数据库 (带认证) 到自动生成的目录 50 $0 -d my_app_db -u admin -p 's3cr3t' 51 52 EOF 53 exit 1 54 } 55 56 # --- 参数解析 (使用 getopts) --- 57 DB_NAME="" 58 COLLECTION_NAME="" 59 OUTPUT_DIR="" 60 USERNAME="" 61 PASSWORD="" 62 63 while getopts "d:c:o:u:p:h" opt; do 64 case ${opt} in 65 d ) DB_NAME=$OPTARG;; 66 c ) COLLECTION_NAME=$OPTARG;; 67 o ) OUTPUT_DIR=$OPTARG;; 68 u ) USERNAME=$OPTARG;; 69 p ) PASSWORD=$OPTARG;; 70 h ) usage;; 71 \? ) echo "无效的选项: -$OPTARG" >&2; usage;; 72 : ) echo "选项 -$OPTARG 需要一个参数。" >&2; usage;; 73 esac 74 done 75 76 # --- 参数验证 --- 77 if [ -z "$DB_NAME" ]; then 78 echo "❌ 错误: 必须使用 -d 提供数据库名称。" 79 usage 80 fi 81 82 if [ -n "$USERNAME" ] && [ -z "$PASSWORD" ]; then 83 echo "❌ 错误: 提供了用户名 (-u),但必须同时提供密码 (-p)。" 84 usage 85 fi 86 87 # --- 准备输出目录 --- 88 if [ -z "$OUTPUT_DIR" ]; then 89 # 如果用户未指定输出目录,则自动创建 90 # 将基路径设置为 dotnet/mongo_export 91 OUTPUT_DIR="dotnet/mongo_export/export_${DB_NAME}_$(date +%Y%m%d_%H%M%S)" 92 echo "未指定输出目录,将使用自动生成的目录: $OUTPUT_DIR" 93 fi 94 95 mkdir -p "$OUTPUT_DIR" 96 if [ $? -ne 0 ]; then 97 echo "❌ 错误: 无法创建输出目录 '$OUTPUT_DIR'。请检查权限。" 98 exit 1 99 fi 100 echo "所有导出的文件将保存在: $OUTPUT_DIR" 101 102 103 # --- 构建命令选项 --- 104 AUTH_OPTIONS="" 105 if [ -n "$USERNAME" ]; then 106 AUTH_OPTIONS="--username $USERNAME --password \"$PASSWORD\" --authenticationDatabase $AUTH_DB" 107 fi 108 109 CONNECTION_OPTIONS="--host $HOST --port $PORT" 110 111 # --- 核心导出逻辑 --- 112 113 if [ -n "$COLLECTION_NAME" ]; then 114 # --- 情况 1: 导出单个集合 --- 115 echo "--------------------------------------------------" 116 echo "模式: 导出单个集合" 117 echo "数据库: '$DB_NAME', 集合: '$COLLECTION_NAME'" 118 119 OUTPUT_FILE="$OUTPUT_DIR/${DB_NAME}_${COLLECTION_NAME}.json" 120 COMMAND="mongoexport --db \"$DB_NAME\" --collection \"$COLLECTION_NAME\" $CONNECTION_OPTIONS $AUTH_OPTIONS --out \"$OUTPUT_FILE\" --jsonArray" 121 122 eval $COMMAND 123 if [ $? -eq 0 ]; then 124 echo "✅ 成功! 文件已保存至: $OUTPUT_FILE" 125 else 126 echo "❌ 失败! 导出时发生错误。" 127 fi 128 else 129 # --- 情况 2: 导出整个数据库 --- 130 echo "--------------------------------------------------" 131 echo "模式: 导出整个数据库" 132 echo "数据库: '$DB_NAME'" 133 134 # 构建 mongosh 连接 URI 135 MONGO_URI="mongodb://" 136 if [ -n "$USERNAME" ]; then 137 ENCODED_USER=$(printf %s "$USERNAME" | jq -sRr @uri) 138 ENCODED_PASS=$(printf %s "$PASSWORD" | jq -sRr @uri) 139 MONGO_URI="${MONGO_URI}${ENCODED_USER}:${ENCODED_PASS}@" 140 fi 141 MONGO_URI="${MONGO_URI}${HOST}:${PORT}/${DB_NAME}?authSource=${AUTH_DB}" 142 143 echo "正在获取集合列表..." 144 # 使用 mongosh 获取集合列表,并处理可能的错误 145 COLLECTIONS=$(mongosh "$MONGO_URI" --quiet --eval "try { db.getCollectionNames().join(' ') } catch (e) { print('') }" 2>/dev/null) 146 147 if [ -z "$COLLECTIONS" ]; then 148 echo "❌ 警告: 在数据库 '$DB_NAME' 中找不到任何集合,或者连接/认证失败。请检查数据库名、认证信息和 MongoDB 服务状态。" 149 # 如果目录是自动创建且为空,则删除 150 [[ "$OUTPUT_DIR" == "dotnet/mongo_export/export_"* ]] && rmdir "$OUTPUT_DIR" 2>/dev/null 151 exit 1 152 fi 153 154 echo "找到的集合: $COLLECTIONS" 155 echo "--------------------------------------------------" 156 157 SUCCESS_COUNT=0 158 FAIL_COUNT=0 159 TOTAL_COUNT=$(echo $COLLECTIONS | wc -w) 160 CURRENT_COUNT=1 161 162 for collection in $COLLECTIONS; do 163 echo " -> [${CURRENT_COUNT}/${TOTAL_COUNT}] 正在导出集合: $collection..." 164 OUTPUT_FILE="$OUTPUT_DIR/${DB_NAME}_${collection}.json" 165 COMMAND="mongoexport --db \"$DB_NAME\" --collection \"$collection\" $CONNECTION_OPTIONS $AUTH_OPTIONS --out \"$OUTPUT_FILE\" --jsonArray" 166 167 eval $COMMAND 168 if [ $? -eq 0 ]; then 169 echo " ✅ 成功! 文件: ${OUTPUT_FILE}" 170 SUCCESS_COUNT=$((SUCCESS_COUNT + 1)) 171 else 172 echo " ❌ 失败! 导出集合 '$collection' 时出错。" 173 FAIL_COUNT=$((FAIL_COUNT + 1)) 174 fi 175 CURRENT_COUNT=$((CURRENT_COUNT + 1)) 176 done 177 178 echo "--------------------------------------------------" 179 echo "导出完成!" 180 echo "总计: $SUCCESS_COUNT 个成功, $FAIL_COUNT 个失败。" 181 fi