如何将Bash循环变量传递至MongoDB命令?
问题解决:Bash变量传递到MongoDB
--eval命令中 你的问题出在单引号的变量屏蔽特性:Bash中用单引号包裹的内容会完全禁止变量替换,所以脚本里的$a并没有被循环中的账号数值替换,而是直接作为字符串传给MongoDB,导致MongoDB报错“$a未定义”。
下面提供两种可行的修复方案:
方案1:替换外层引号为双引号并转义MongoDB的$符号
把包裹MongoDB命令的单引号改成双引号,同时对MongoDB语法里的$and、$gt、$lt添加反斜杠转义(避免Bash把这些$当成变量解析):
#!/usr/bin/bash for a in $(cat /tmp/account.txt); do mongo --authenticationDatabase admin -u 'xxxxxx' -p 'xxxxxxxxx' --quiet --eval "db.executions.find({ \$and : [ { \"account_id\" : $a }, { \"status\" : \"running\" }, { \"created_at\" : { \"\$gt\" : ISODate(\"2022-09-01T00:00:00.000Z\") } }, { \"created_at\" : { \"\$lt\" : ISODate(\"2022-10-01T00:00:00.000Z\") } } ] } ,{\"account_id\":1,\"created_at\":1} ).count()" selfservice_production; done
方案2:字符串拼接插入变量(推荐)
通过关闭单引号、插入变量、再重新打开单引号的方式,直接把Bash变量$a嵌入MongoDB命令中,无需转义MongoDB的$符号:
#!/usr/bin/bash for a in $(cat /tmp/account.txt); do mongo --authenticationDatabase admin -u 'xxxxxx' -p 'xxxxxxxxx' --quiet --eval 'db.executions.find({ $and : [ { "account_id" : '"$a"' }, { "status" : "running" }, { "created_at" : { "$gt" : ISODate("2022-09-01T00:00:00.000Z") } }, { "created_at" : { "$lt" : ISODate("2022-10-01T00:00:00.000Z") } } ] } ,{"account_id":1,"created_at":1} ).count()' selfservice_production; done
这里的'"$a"'是关键:先关闭外层单引号,用双引号包裹$a(保证变量安全解析,即使账号包含特殊字符也能兼容),再重新打开单引号继续拼接后续命令。
额外提示
- 读取文件内容时,优先使用
$(cat /tmp/account.txt)替代反引号语法,这是Bash的规范写法。 - 你的场景中账号都是数字,两种方案都能生效;如果账号包含空格、引号等特殊字符,方案2的兼容性更好。
内容的提问来源于stack exchange,提问作者Renu prashanth M
相关产品推荐
相关产品推荐

