Windows开发不熟悉shell,启动MongoDB的bash脚本运行报括号无效错误求解
问题根源
你遇到的报错本质是把两个完全独立的语法体系、执行流程搞混了:
- 脚本前半段的
docker-compose、docker exec命令是bash shell的语法,由bash解析执行 - 后面的
rs.initiate(...)是Mongo交互shell的专属语法,是你本来要等docker exec进入Mongo交互终端之后,手动敲给Mongo程序执行的内容,根本不该写在bash脚本的正文里
当bash顺序执行完docker exec -it localmongo1 mongo之后,会继续往下读脚本内容,碰到独立成行的rs.initiate(时,会把它当成要执行的shell命令,碰到没有合法上下文的(就会直接报语法错误。你之前尝试转义括号没用,是因为问题根本不是括号需要转义,是这些Mongo命令从一开始就不该出现在bash的解析上下文里。
可行的修改方案
方案1:非交互式自动执行初始化(最适合自动化跑脚本)
完全不需要手动进入Mongo终端敲命令,直接把初始化逻辑内嵌到脚本里,全程自动执行:
#!/bin/bash # 启动所有MongoDB相关容器 docker-compose -f docker-compose.mongo.yml up -d # 等待5秒让容器内的MongoDB服务完全就绪,避免刚启动就连不上 sleep 5 # 把副本集初始化命令直接通过--eval参数传给容器内的mongo程序执行 docker exec localmongo1 mongo --eval " rs.initiate( { _id : 'rs0', members: [ { _id : 0, host : 'mongo1:27017' }, { _id : 1, host : 'mongo2:27017' }, { _id : 2, host : 'mongo3:27017', arbiterOnly: true } ] } ) "
注意:这里的
docker exec去掉了-it参数,因为非交互式执行命令不需要分配虚拟终端,避免参数冗余带来的异常。
方案2:自动完成初始化后再进入交互式Mongo终端
如果你跑完脚本还需要留在Mongo shell里操作,就把交互式登录的步骤放在最后执行:
#!/bin/bash docker-compose -f docker-compose.mongo.yml up -d sleep 5 # 先自动完成副本集初始化 docker exec localmongo1 mongo --eval "rs.initiate({_id:'rs0', members:[{_id:0,host:'mongo1:27017'},{_id:1,host:'mongo2:27017'},{_id:2,host:'mongo3:27017',arbiterOnly:true}]})" # 最后启动交互式Mongo终端 docker exec -it localmongo1 mongo
Windows环境额外注意事项
- 保存
docker.sh脚本时,要把文件换行符设置为LF,不要用Windows默认的CRLF,不然运行时会触发不可预期的解析错误 - 不要把Mongo的语法直接写在bash脚本的正文里等bash执行,所有Mongo相关的命令要么通过
--eval参数传递,要么等进入Mongo交互终端之后再手动输入。
内容的提问来源于stack exchange,提问作者thatguy
相关产品推荐
相关产品推荐

