如何通过shell脚本执行mongo命令?

Sta*_*low 375 bash shell sh mongodb

我想在shell脚本中执行mongo命令.

我尝试了以下方式test.sh

#!/bin/sh
mongo myDbName
db.mycollection.findOne()
show collections
Run Code Online (Sandbox Code Playgroud)

当我执行上面的脚本./test.sh

然后建立了mongo连接,但未执行下一个命令

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

请帮我

the*_*cer 421

如果命令--eval只是一个命令,您还可以使用该标志评估命令.

mongo --eval "printjson(db.serverStatus())"
Run Code Online (Sandbox Code Playgroud)

请注意:如果您使用的是Mongo运算符,从$符号开始,您需要用单引号括起eval参数,以防止shell将运算符作为环境变量进行求值:

mongo --eval 'db.mycollection.update({"name":"foo"},{$set:{"this":"that"}});' myDbName
Run Code Online (Sandbox Code Playgroud)

否则你可能会看到这样的事情:

mongo --eval "db.test.update({\"name\":\"foo\"},{$set:{\"this\":\"that\"}});"
> E QUERY    SyntaxError: Unexpected token :
Run Code Online (Sandbox Code Playgroud)

  • 对于`.find()`操作,您需要在结果对象上调用一个操作来打印文档,例如`toArray()`或`shellPrint()`.例如,`mongo userdb --eval"printjson(db.users.find().toArray())"` (34认同)
  • 谢谢@Gingi - 我首选的方法是`mongo mydb --eval"db.users.find({a:'b'}).pretty().shellPrint()"`... simples :) (9认同)
  • @Amida你可以做`mongo --eval"db.version()"--quiet`例如以避免打印你说的所有噪音 (6认同)
  • 我必须指定连接字符串,如mongo <ip>:<port>/db --eval"printjson(db.serverStatus())"或mongo <ip>:<port>/db <mongoCommands.js以防止它总是连接到"测试" (4认同)
  • 我希望我能得到所有的结果,而不是看到它为"更多"打字"打字" (4认同)
  • 如何定义我的服务器名和数据库名? (3认同)
  • 虽然这有效,但问题在于不仅发送查询结果,还发送诸如连接状态消息之类的噪音:MongoDB shell version: 2.6.0 connected to: myhost DBQuery: mydb.mycollection -&gt; { } MongoDB shell version: 2.6 .0 连接到:myhost `query result` 更多噪音 (2认同)
  • @colintobing `mongo dbname --eval 'db.test.findOne()'` (2认同)

Mat*_*att 306

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

然后执行 mongo < yourFile.js

例如:

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

use sample  //db name
show collections
Run Code Online (Sandbox Code Playgroud)

将此文件保存在"c:\ db-scripts"中

然后在cmd提示符下转到"c:\ db-scripts"

C:\db-scripts>mongo < demo.js
Run Code Online (Sandbox Code Playgroud)

这将在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>
Run Code Online (Sandbox Code Playgroud)

  • 相当简单..你可以使用与mongo shell输入完全相同的命令,将这些命令保存到`.js`文件中,并将其作为参数传递给`mongo`命令. (12认同)
  • @Matt - 请注意,shell提供的非JavaScript命令在执行的JavaScript文件中不可用,因此`use dbName`和`show dbs`将在shell的内部提示符下工作,但不能在`.js`中工作.文件.非JavaScript命令有JavaScript等价物,因此这不是限制,只是您需要注意的事项. (8认同)
  • 值得注意的是,在执行脚本(如果提供)时,mongo解释器的--eval语句(如果提供)中设置的任何内容都将保留在范围内.您可以使用它使您的脚本更具可重用性,例如.mongo --eval"somevar ='someval';" db_name script_that_uses_somevar.js (7认同)
  • 如果需要指定数据库的名称,用户名,密码,可以使用空格"mongo dbName -u userName -p"密码"scriptToRun.js" (2认同)
  • 如果您想要动态行为,即传递参数:“mongo &lt; demo.js arg1 arg2 arg3”,那么这不起作用 - 您将如何在“js”文件中读取它们? (2认同)
  • 使用 `mongo --quiet` 不打印再见和版本。 (2认同)

Ant*_*jdr 94

这在Linux下适用于我:

mongo < script.js
Run Code Online (Sandbox Code Playgroud)

  • 当然不必是.js文件 (2认同)

The*_*heo 62

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

db.mycollection.findOne()
db.getCollectionNames().forEach(function(collection) {
  print(collection);
});
Run Code Online (Sandbox Code Playgroud)

然后运行它mongo myDbName test.js.

  • 如何从bash将值传递到脚本?我想将名称插入db中,该名称在bash中作为变量提供,我想将其传递给script(js) (2认同)

tha*_*smt 40

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

该页面的示例包括:

mongo server:27017/dbname --quiet my_commands.js
mongo test --eval "printjson(db.getCollectionNames())"
Run Code Online (Sandbox Code Playgroud)


小智 30

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

function testMongoScript {
    mongo <<EOF
    use mydb
    db.leads.findOne()
    db.leads.find().count()
EOF
}
Run Code Online (Sandbox Code Playgroud)

  • 很棒的答案!对于多个命令,这也有效:`echo -e"使用mydb \ndb.leads.findOne()\ndb.leads.find().count()"| mongo` (12认同)
  • 实际上,您可以从 mongo 脚本内切换数据库:`db = db.getSiblingDB('otherdb');` (2认同)

Ed *_*ams 21

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

mongo --host="the.server.ip:port" databaseName theScript.js 
Run Code Online (Sandbox Code Playgroud)

  • Thx为主机名标志 (3认同)

Joh*_*ood 18

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

#!/usr/bin/sh

mongo <db> <<EOF
db.<collection>.find({
  fieldName: { $exists: true }
})
.forEach( printjson );
EOF
Run Code Online (Sandbox Code Playgroud)

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

#!/usr/bin/sh

mongo <db> <<EOF
db.<collection>.find({
  fieldName: { : true }
})
.forEach( printjson );
EOF
Run Code Online (Sandbox Code Playgroud)

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

#!/usr/bin/sh

mongo <db> <<EOF
db.<collection>.find({
  fieldName: { \$exists: true }
})
.forEach( printjson );
EOF
Run Code Online (Sandbox Code Playgroud)

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

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

#!/usr/bin/sh

mongo <db> <<\EOF
db.<collection>.find({
  fieldName: { $exists: true }
})
.forEach( printjson );
EOF
Run Code Online (Sandbox Code Playgroud)

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

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

#!/bin/env mongo
<some mongo stuff>
Run Code Online (Sandbox Code Playgroud)

此解决方案有几个问题:

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

  2. 它的功能与"mongo <some-js-file>"完全相同,这意味着它不允许您使用"use <db>"命令.

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

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

#!/bin/env mongo
db = db.getSiblingDB('<db>');
<your script>
Run Code Online (Sandbox Code Playgroud)

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


Mos*_* Xu 16

如果您启用了身份验证:

mongo -u username -p password --authenticationDatabase auth_db_name < your_script.js
Run Code Online (Sandbox Code Playgroud)


GSK*_*GSK 14

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

#!/bin/sh
mongo < file.js
Run Code Online (Sandbox Code Playgroud)

file.js写你的mongo查询:

db.collection.find({"myValue":null}).count();
Run Code Online (Sandbox Code Playgroud)


Mar*_*ler 13

这个怎么样:

echo "db.mycollection.findOne()" | mongo myDbName
echo "show collections" | mongo myDbName
Run Code Online (Sandbox Code Playgroud)


Mat*_*ark 12

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

mongo <dbname> --eval "printjson(db.something.find())"
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你包括命令的`<dbname>`部分:) (2认同)

Ard*_*dhi 10

就我而言,我可以方便地将其\n用作下一个要执行的 mongo 命令的分隔符,然后将它们通过管道传输到mongo

echo $'use your_db\ndb.yourCollection.find()' | mongo
Run Code Online (Sandbox Code Playgroud)


tgo*_*eil 7

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

use someDb
db.someColl.find()
Run Code Online (Sandbox Code Playgroud)

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

mongo < mongoCmds.js
Run Code Online (Sandbox Code Playgroud)

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

printf "use someDb\ndb.someColl.find()" | mongo
Run Code Online (Sandbox Code Playgroud)

Bash printf比它更强大echo并且允许\n命令之间强制它们在多行上.


小智 5

mongo <<EOF
use <db_name>
db.getCollection("<collection_name>").find({})
EOF
Run Code Online (Sandbox Code Playgroud)