Python调用Mongo CLI在3.4.x版本认证失败,低版本正常求助
解决MongoDB 3.4.x中su执行mongo命令认证失败的问题
首先咱们来拆解你的问题:这条命令在MongoDB 3.4以下版本能正常跑,但升级到3.4.x后就触发认证失败,核心原因大概率和认证机制变更或者shell命令的引号解析逻辑有关,下面分两种场景给你解决方案:
场景1:手动执行命令也失败(排除Python执行的影响)
如果直接在终端敲这条命令也报错,那问题出在MongoDB的用户认证配置上:
- MongoDB 3.4开始默认使用
SCRAM-SHA-1认证机制,而3.0及更早版本默认是MONGODB-CR。如果你的admin用户是在旧版本创建的,可能还绑定着旧的认证机制,导致3.4无法识别。 - 修复步骤:
- 临时关闭MongoDB认证:修改
mongod.conf配置文件,注释掉security.authorization: enabled这一行,然后重启mongod服务。 - 无认证连接MongoDB:执行
mongo admin。 - 更新admin用户的认证机制:
// 方法1:重置密码同时指定新机制 db.changeUserPassword("admin", "password", {mechanism: "SCRAM-SHA-1"}) // 方法2:直接更新用户的认证机制列表 db.updateUser("admin", {authenticationMechanisms: ["SCRAM-SHA-1"]}) - 恢复认证配置,重启mongod服务,再重新执行你的命令。
- 临时关闭MongoDB认证:修改
场景2:手动执行正常,但Python中执行失败
这基本是Python执行shell命令时的引号转义问题:原命令里--eval 'version()'的单引号,在su -c的双引号包裹下,可能被外层shell提前解析,导致mongo命令接收到的--eval参数不完整。
给你两种解决思路:
方案A:调整引号嵌套方式
把--eval的单引号换成双引号,外层用单引号包裹su -c的参数,避免解析冲突:
import subprocess cmd = '''su - mongod -c '/usr/bin/mongo admin -u admin -p password --authenticationDatabase admin --port 27017 --eval "version()"' ''' result = subprocess.run(cmd, shell=True, capture_output=True, text=True) print(result.stdout) print(result.stderr)
方案B:用subprocess列表参数传递(更安全)
避开shell解析逻辑,把命令拆分成列表形式,彻底不用处理引号转义:
import subprocess # 注意:su -c 需要把整个mongo命令作为一个独立参数 cmd = [ 'su', '-', 'mongod', '-c', '/usr/bin/mongo admin -u admin -p password --authenticationDatabase admin --port 27017 --eval "version()"' ] result = subprocess.run(cmd, capture_output=True, text=True) print(result.stdout) print(result.stderr)
额外排查小技巧
- 确认
mongod用户有权限执行/usr/bin/mongo命令,且能访问MongoDB的端口或socket文件。 - 查看MongoDB日志(通常在
/var/log/mongodb/mongod.log),里面会有更详细的认证失败原因,比如用户不存在、密码不匹配、机制不兼容等。
内容的提问来源于stack exchange,提问作者Felicia Amy
相关产品推荐
相关产品推荐

