我想在shell脚本中执行mongo命令,例如在脚本test.sh中:
mongo
test.sh
#!/bin/sh mongo myDbName db.mycollection.findOne() show collections
当我通过./test.sh执行这个脚本时,就会建立到MongoDB的连接,但不会执行以下命令。
./test.sh
如何通过shell脚本test.sh执行其他命令?
把你的mongo脚本放到.js文件中。
.js
然后执行mongo < yourFile.js
mongo < yourFile.js
例:
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的文件中:
test.js
db.mycollection.findOne() db.getCollectionNames().forEach(function(collection) { print(collection); });
然后用mongo myDbName test.js运行它。
mongo myDbName test.js
你也可以使用--eval标志来计算一个命令,如果它只是一个命令的话。
--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脚本也很适合我……definite不得不使用Antonin一开始提到的重定向…这让我产生了测试这里文档的想法。
function testMongoScript { mongo <<EOF use mydb db.leads.findOne() db.leads.find().count() EOF }
在我的设置中,我必须使用:
mongo --host="the.server.ip:port" databaseName theScript.js
mongosh --host="the.server.ip:port" databaseName theScript.js
还有一个官方文档页面关于这个。
该页面的例子包括:
mongo server:27017/dbname --quiet my_commands.js mongo test --eval "printjson(db.getCollectionNames())"
我使用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>
就像生活中的任何事情一样,“做这件事的方法不止一种!”
这个怎么样:
echo "db.mycollection.findOne()" | mongo myDbName echo "show collections" | mongo myDbName
——shell标志也可以用于javascript文件
mongo --shell /path/to/jsfile/test.js
谢谢你printf!在Linux环境中,有一种更好的方法,可以只让一个文件运行。假设你有两个文件,mongoCmds.js有多个命令:
printf
mongoCmds.js
use someDb db.someColl.find()
然后是驱动程序shell文件runMongoCmds.sh
runMongoCmds.sh
mongo < mongoCmds.js
更新版本的mongodb
mongosh < mongoCmds.js
相反,只有一个文件runMongoCmds.sh包含
printf "use someDb\ndb.someColl.find()" | mongo
Bash的printf比echo健壮得多,并允许命令之间的\n强制它们在多行上。
echo
\n
根据theTuxRacer的建议,你可以使用eval命令,对于那些像我一样缺少它的人,如果你不想对默认db执行form操作,你也可以添加你的db名称。
theTuxRacer
mongo <dbname> --eval "printjson(db.something.find())"
mongosh <dbname> --eval "printjson(db.something.find())"
mongo db_name --eval "db.user_info.find().forEach(function(o) {print(o._id);})"
最近从mongodb迁移到Postgres。这是我使用脚本的方式。
mongo < scripts.js > inserts.sql
读取scripts.js并输出重定向到inserts.sql。
scripts.js
inserts.sql
scripts.js看起来像这样
use myDb; var string = "INSERT INTO table(a, b) VALUES"; db.getCollection('collectionName').find({}).forEach(function (object) { string += "('" + String(object.description) + "','" + object.name + "'),"; }); print(string.substring(0, string.length - 1), ";");
inserts.sql看起来像这样
INSERT INTO table(a, b) VALUES('abc', 'Alice'), ('def', 'Bob'), ('ghi', 'Claire');
如果您已启用身份验证:
mongo -u username -p password --authenticationDatabase auth_db_name < your_script.js
更新版本
mongosh -u username -p password --authenticationDatabase auth_db_name < your_script.js
创建一个脚本文件;写命令:
#!/bin/sh mongo < file.js
对于更新的版本 mongosh & lt;file.js < / p >
在file.js中编写mongo查询:
file.js
db.collection.find({"myValue":null}).count();
如果你想用一条线来处理它,这是一个简单的方法。
file.sh --> db.EXPECTED_COLLECTION.remove("_id":1234) cat file.sh | mongo <EXPECTED_COLLECTION>
mongo <<EOF use <db_name> db.getCollection("<collection_name>").find({}) EOF
在我的例子中,我可以方便地使用\n作为我想要执行的下一个mongo命令的分隔符,然后将它们输送到mongo
echo $'use your_db\ndb.yourCollection.find()' | mongo
echo $'use your_db\ndb.yourCollection.find()' | mongosh
单shell脚本解决方案,能够传递mongo参数(--quiet, dbname等):
--quiet
#!/usr/bin/env -S mongo --quiet localhost:27017/test cur = db.myCollection.find({}); while(cur.hasNext()) { printjson(cur.next()); }
-S标志可能不能在所有平台上工作。
-S
当使用复制集时,必须在PRIMARY上进行写操作,所以我通常使用这样的语法,以避免弄清楚哪个主机是主主机:
mongo -host myReplicaset/anyKnownReplica
遗留的mongo shell已从MongoDB中移除,并将于2022年发布第6版
有一种使用新shell mongosh执行shell脚本的新方法
从编写脚本的shell文档开始: