我想在shell脚本中执行mongo命令,例如在脚本test.sh中:
#!/bin/sh
mongo myDbName
db.mycollection.findOne()
show collections
当我通过./test.sh执行这个脚本时,会建立到MongoDB的连接,但不会执行以下命令。
如何通过shell脚本test.sh执行其他命令?
我想在shell脚本中执行mongo命令,例如在脚本test.sh中:
#!/bin/sh
mongo myDbName
db.mycollection.findOne()
show collections
当我通过./test.sh执行这个脚本时,会建立到MongoDB的连接,但不会执行以下命令。
如何通过shell脚本test.sh执行其他命令?
当前回答
我使用David Young提到的“heredoc”语法。但这里有一个问题:
#!/usr/bin/sh
mongo <db> <<EOF
db.<collection>.find({
fieldName: { $exists: true }
})
.forEach( printjson );
EOF
上面的代码将不起作用,因为shell将看到短语“$exists”,并将其替换为名为“exists”的环境变量的值。它很可能不存在,所以在shell扩展之后,它变成:
#!/usr/bin/sh
mongo <db> <<EOF
db.<collection>.find({
fieldName: { : true }
})
.forEach( printjson );
EOF
为了让它通过你有两个选择。一个很丑,一个很好。首先是最丑的:转义$符号:
#!/usr/bin/sh
mongo <db> <<EOF
db.<collection>.find({
fieldName: { \$exists: true }
})
.forEach( printjson );
EOF
我不建议这样做,因为很容易忘记逃避。
另一个选择是转义EOF,就像这样:
#!/usr/bin/sh
mongo <db> <<\EOF
db.<collection>.find({
fieldName: { $exists: true }
})
.forEach( printjson );
EOF
现在,你可以在heredoc中放入任何你想要的美元符号,美元符号会被忽略。缺点:如果你需要在mongo脚本中放置shell参数/变量,这是行不通的。
另一个你可以玩的选择是弄乱你的“shebang”。例如,
#!/bin/env mongo
<some mongo stuff>
这种解决方案存在几个问题:
只有当你试图使mongo shell脚本从命令行可执行时,它才有效。您不能将常规shell命令与mongo shell命令混合使用。这样做所节省的就是不必在命令行上输入“mongo”…(当然有足够的理由) 它的功能完全类似于“mongo <some-js-file>”,这意味着它不允许您使用“use <db>”命令。
我尝试将数据库名称添加到shebang中,您可能认为这可以工作。不幸的是,根据系统处理shebang行的方式,第一个空格之后的所有内容都作为单个参数(好像加了引号)传递给env命令,env无法找到并运行它。
相反,你必须将数据库更改嵌入到脚本本身中,如下所示:
#!/bin/env mongo
db = db.getSiblingDB('<db>');
<your script>
就像生活中的任何事情一样,“做这件事的方法不止一种!”
其他回答
将mongo脚本放到.js文件中。
然后执行mongo < yourFile.js
Ex:
Demo.js //file有你的脚本
use sample //db name
show collections
将此文件保存在“c:\db-scripts”中
然后在cmd提示符中转到"c:\db-scripts"
C:\db-scripts>mongo < demo.js
这将在mongo中执行代码并显示输出
C:\db-scripts>mongo < demo.js
Mongo shell version: 3.0.4
Connecting to: test
switched to db sample
users //collection name
tasks //collection name
bye
C:\db-scripts>
把它放在一个名为test.js的文件中:
db.mycollection.findOne()
db.getCollectionNames().forEach(function(collection) {
print(collection);
});
然后用mongo myDbName test.js运行它。
你也可以使用——eval标志对命令求值,如果它只是一个命令的话。
mongo --eval "printjson(db.serverStatus())"
请注意:如果你使用Mongo操作符,以$符号开始,你需要用单引号包围eval参数,以防止shell将操作符作为环境变量来计算:
mongo --eval 'db.mycollection.update({"name":"foo"},{$set:{"this":"that"}});' myDbName
否则你可能会看到这样的东西:
mongo --eval "db.test.update({\"name\":\"foo\"},{$set:{\"this\":\"that\"}});"
> E QUERY SyntaxError: Unexpected token :
这适用于我在Linux下:
mongo < script.js
mongodb的更新版本
mongosh < script.js
单shell脚本解决方案,能够传递mongo参数(——quiet, dbname,等):
#!/usr/bin/env -S mongo --quiet localhost:27017/test
cur = db.myCollection.find({});
while(cur.hasNext()) {
printjson(cur.next());
}
-S标志可能不适用于所有平台。