我想在shell脚本中执行mongo命令,例如 在脚本test.sh中:

#!/bin/sh

mongo myDbName

db.mycollection.findOne()

show collections

当我通过./test.sh执行此脚本时,将建立与MongoDB的连接,但不执行以下命令。

如何通过shell脚本test.sh执行其他命令?

您还可以使用--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 :

对于.find()操作,您需要对结果对象调用操作以打印文档,例如toArray()或shellPrint()。例如,mongo userdb --eval"printjson(db.users.find().toArray())"

我必须指定连接字符串,如mongo :/ db --eval"printjson(db.serverStatus())"或mongo :/ db 谢谢@Gingi - 我的首选方法是mongo mydb --eval"db.users.find({a:'b'}).pretty().shellPrint()" ... simples :)

我希望我能得到所有的结果,而不是看到它为"更多"打字"打字"

虽然这有效,但问题是不仅发送了查询结果而且还发送了连接状态消息等噪声:MongoDB shell版本:2.6.0连接到:myhost DBQuery:mydb.mycollection - > {} MongoDB shell版本:2.6 .0连接到:myhost query result更多噪音

如何定义我的servername和dbname?

@Amida你可以做mongo --eval"db.version()" --quiet,以避免打印你说的所有噪音

如果您想要有效的JSON输出,请使用JSON.stringify()而不是printjson()

mongo --eval"db.test.update({"name":"foo"},{$set:{"this":"that"}});"> E QUERY SyntaxError: Unexpected token :如果您看到此错误,请不要尝试使用单引号或双引号中的文本$ set来解决此问题,这会导致数据丢失,因为脚本会将$set理解为新属性且没有$ set,文档被新文档覆盖,其中包含一些像"": this:"that"这样的字段。

双引号版本如果你转义任何这样的$运算符都有效:mongo --eval"db.${Collection}.updateMany({},{ \$set: {${Field}:${Value}}});"允许包含内联的shell标记

@colintobing mongo dbname --eval 'db.test.findOne()'

将您的mongo脚本放入.js文件中。

然后执行mongo < yourFile.js

例如:

demo.js //文件有你的脚本

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>

从字面上看......您可以使用与输入到mongo shell完全相同的命令,将这些命令保存到.js文件中,并将其作为参数传递给mongo命令。

值得注意的是,在执行脚本(如果提供)时,mongo解释器的--eval语句(如果提供)中设置的任何内容都将保留在范围内。您可以使用它使您的脚本更具可重用性,例如。 mongo --eval"somevar ='someval';" db_name script_that_uses_somevar.js

@Matt - 请注意,shell提供的非JavaScript命令在执行的JavaScript文件中不可用,因此use dbName和show dbs将在shell的内部提示符下工作,但不能在.js文件中工作。非JavaScript命令有JavaScript等价物,因此这不是限制,只是您需要注意的事项。

如果需要指定数据库的名称,用户名,密码,则可以执行mongo dbName -u userName -p"password with spaces" scriptToRun.js

如果你想要一个动态行为,即传递参数:mongo < demo.js arg1 arg2 arg3 - 这将如何在js文件中读取它们?

有没有办法让mongo提示打开? AKA我不希望mongo对我说"再见"。

如何在远程服务器上运行此脚本?mongodb:uri:mongodb:// user:password@mongodb01d.mydomain.com:27017 / mydb

使用mongo --quiet表示不打印再见和版本。

这在Linux下适用于我:

mongo < script.js

当然,它不必是.js文件

即使在Windows上也能工作

在PowerShell中不起作用,在Bash中有效

把它放在一个名为test.js的文件中:

db.mycollection.findOne()

db.getCollectionNames().forEach(function(collection) {

print(collection);

});

然后用mongo myDbName test.js运行它。

如何从bash传递值到脚本?我想在db中插入名称作为变量,我希望将其传递给脚本(js)

这在PowerShell中有效

这是一个更好的解决方案,当我将文件传输到mongo时,我得到js语法错误。

还有一个关于此的官方文档页面。

该页面的示例包括:

mongo server:27017/dbname --quiet my_commands.js

mongo test --eval"printjson(db.getCollectionNames())"

下面的shell脚本对我来说也很好用...明确必须使用Antonin最初提到的重定向...这给了我测试这里文档的想法。

function testMongoScript {

mongo <

use mydb

db.leads.findOne()

db.leads.find().count()

EOF

}

很棒的答案!对于多个命令,这也有效:echo -e"use mydb

db.leads.findOne()

db.leads.find().count()" | mongo

绝对有用,因为你不能在JS文件中使用"use mydb"。

这次真是万分感谢!最后我可以打电话给use another_db。 :-)

实际上,您可以在mongo脚本中切换DB:db = db.getSiblingDB('otherdb');

在我的设置中,我必须使用:

mongo --host="the.server.ip:port" databaseName theScript.js

Thx为主机名标志

+1为databaseName :)

我使用了David Young提到的"heredoc"语法。但是有一个问题:

#!/usr/bin/sh

mongo ;lt;db;gt; ;lt;;lt;EOF

db.;lt;collection;gt;.find({

fieldName: { $exists: true }

})

.forEach( printjson );

EOF

以上操作不起作用,因为shell将看到短语"$ exists",并用名为"exists"的环境变量的值替换。哪个可能不存在,所以在shell扩展后,它变为:

#!/usr/bin/sh

mongo ;lt;db;gt; ;lt;;lt;EOF

db.;lt;collection;gt;.find({

fieldName: { : true }

})

.forEach( printjson );

EOF

为了让它通过你有两个选择。一个是丑陋的,一个是相当不错的。首先,丑陋的一个:逃避$符号:

#!/usr/bin/sh

mongo ;lt;db;gt; ;lt;;lt;EOF

db.;lt;collection;gt;.find({

fieldName: { \$exists: true }

})

.forEach( printjson );

EOF

我不推荐这个,因为很容易忘记逃避。

另一个选择是逃避EOF,如下所示:

#!/usr/bin/sh

mongo ;lt;db;gt; ;lt;;lt;\EOF

db.;lt;collection;gt;.find({

fieldName: { $exists: true }

})

.forEach( printjson );

EOF

现在,您可以将所需的所有美元符号放在您的heredoc中,并忽略美元符号。缺点:如果你需要在你的mongo脚本中放置shell参数/变量,这不起作用。

你可以玩的另一个选择是弄乱你的shebang。例如,

#!/bin/env mongo

;lt;some mongo stuff;gt;

此解决方案有几个问题:

它仅在您尝试从命令行生成mongo shell脚本时才有效。您不能将常规shell命令与mongo shell命令混合使用。而你所节省的就是不必在命令行输入"mongo"......(理由当然,这样)

它的功能与"mongo; lt; some-js-file; gt;"完全相同这意味着它不允许你使用"use; lt; db; gt;"命令。

我已经尝试将数据库名称添加到shebang,您认为它可以工作。不幸的是,系统处理shebang行的方式,第一个空格之后的所有内容都作为单个参数(如同引用)传递给env命令,并且env无法找到并运行它。

相反,您必须在脚本本身中嵌入数据库更改,如下所示:

#!/bin/env mongo

db = db.getSiblingDB(';lt;db;gt;');

;lt;your script;gt;

与生活中的任何事物一样,"有多种方法可以做到!"

这个对我有用:#!/ usr / bin / mongo; lt; db_name; gt;

如果您启用了身份验证:

mongo -u username -p password --authenticationDatabase auth_db_name ;lt; your_script.js

这个怎么样:

echo"db.mycollection.findOne()" | mongo myDbName

echo"show collections" | mongo myDbName

或者更具可读性:echo; quot; db.mycollection.findOne(); quot;| mongo myDbName --quiet | python -m json.tool

这对于在加载.mongorc之后执行某些操作很有用(docs.mongodb.org/manual/reference/program/mongo/;hellip;)

正如theTuxRacer所建议的那样,您可以使用eval命令,对于那些像我一样丢失它的人,如果您不想在默认数据库上执行操作,也可以添加数据库名称。

mongo ;lt;dbname;gt; --eval"printjson(db.something.find())"

谢谢你包括命令的;lt;dbname;gt;部分:)

创建一个脚本文件; 写命令:

#!/bin/sh

mongo ;lt; file.js

在file.js中编写您的mongo查询:

db.collection.find({"myValue":null}).count();

谢谢printf!在Linux环境中,这是一个更好的方法,只有一个文件运行show。假设您有两个文件,mongoCmds.js包含多个命令:

use someDb

db.someColl.find()

然后是驱动程序shell文件,runMongoCmds.sh

mongo ;lt; mongoCmds.js

相反,只有一个文件,runMongoCmds.sh包含

printf"use someDb

db.someColl.find()" | mongo

Bash的printf比echo更强大,并允许命令之间的强制它们在多行上。

mongo db_name --eval"db.user_info.find().forEach(function(o) {print(o._id);})"

mongo ;lt;;lt;EOF

use ;lt;db_name;gt;

db.getCollection(";lt;collection_name;gt;").find({})

EOF

或者对于短命令:mongo ;lt;;lt;;lt; ;#39;show dbs;#39;

--shell标志也可用于javascript文件

mongo --shell /path/to/jsfile/test.js

我认为这只是在js执行后打开shell? mongo ;#47;path;#47;to;#47;jsfile;#47;test.js也会对js进行解释。

如果你想用一条线处理它,这是一个简单的方法。

file.sh --;gt; db.EXPECTED_COLLECTION.remove("_id":1234)

cat file.sh | mongo ;lt;EXPECTED_COLLECTION;gt;

在我的情况下,我可以方便地使用作为我要执行的下一个mongo命令的分隔符,然后将它们传递给mongo

echo $'use your_db

db.yourCollection.find()' | mongo

最近从mongodb迁移到Postgres。 这就是我使用脚本的方式。

mongo ;lt; scripts.js ;gt; 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');

非常有趣,但关于原始问题的主题。

How to execute mongo commands through shell scripts?这不是偏离主题的。 事实上,由于标题,我达成了这个问题。 所以像我这样的人有益于阅读这样的答案。 另外,我在示例中给出了一个非常有用的方法,而不是玩具示例。

我在更大的Bash脚本中编写了运行Mongo Shell脚本的各种选项

单shell脚本解决方案,能够传递mongo参数(--quiet,dbname等):

#!/usr/bin/env -S mongo --quiet localhost:27017/test

cur = db.myCollection.find({});

while(cur.hasNext()) {

printjson(cur.next());

}

-S标志可能不适用于所有平台。

Logo

更多推荐