Bash脚本调用mongo初始化MongoDB分片副本集变量被加单引号问题
问题根源
- 你看到的
set -x输出里的额外单引号是Bash打印调试信息时用来标注参数边界的标记,不是实际插入到命令里的内容,真实故障是参数拆分错误+引号嵌套逻辑错误:- 最后一行执行mongo命令时,你把包含空格的
${shard_ips_arr}直接放在无引号的上下文中,Bash会把变量里的每个空格作为分隔符,把内容拆成多个独立的参数传递给mongo,导致eval接收到的内容是碎的。 - 单引号内部的变量不会被Bash展开,你拼接
shardreplset${replication_set_number}时的引号嵌套逻辑完全错误,导致副本集名称的参数也不符合预期。
- 最后一行执行mongo命令时,你把包含空格的
修复方案
不要直接在命令行里拼接零散的字符串,先把完整的rs.initiate参数作为单个变量提前拼好,再传递给mongo,修改后的完整脚本如下:
#!/bin/bash set -x export shard_ips='[10.0.0.206,10.0.0.142,10.0.0.234]' export shard_count=3 export replication_set_number=1 shard_count=$((shard_count-1)) IFS="," read -a shard_ips_arr <<< $(echo $shard_ips | tr -d '[]') primary_shard_ip=${shard_ips_arr[0]} count=0 # 先生成每个member的JSON片段 members=() while [ $count -le ${shard_count} ] do members+=("{ _id: $count, host: \"${shard_ips_arr[$count]}:27017\" }") count=$(($count + 1)) done function join { local IFS="$1"; shift; echo "$*"; } shard_members=$(join , "${members[@]}") # 提前拼好完整的eval参数,用双引号包裹保证变量正常展开,内部双引号转义 eval_arg="rs.initiate( { _id: \"shardreplset${replication_set_number}\", members: [ ${shard_members} ] } )" # 直接传递变量,加双引号保证作为单个参数传递 mongo --eval "${eval_arg}" "${primary_shard_ip}:27017"
验证逻辑
修改后你可以执行前先打印echo "${eval_arg}",输出内容会和你预期的rs.initiate参数完全一致,不会出现参数拆分问题。
内容的提问来源于stack exchange,提问作者Matthew Mcloughlin
相关产品推荐
相关产品推荐

