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

时间:2011-01-29 15:26:02

标签: mongodb bash shell sh

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

#!/bin/sh
mongo myDbName
db.mycollection.findOne()
show collections

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

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

22 个答案:

答案 0 :(得分:382)

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

答案 1 :(得分:288)

将您的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>

答案 2 :(得分:92)

这适用于Linux:

mongo < script.js

答案 3 :(得分:57)

将其放在名为test.js的文件中:

db.mycollection.findOne()
db.getCollectionNames().forEach(function(collection) {
  print(collection);
});

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

答案 4 :(得分:37)

此页面也有一个official documentation页面。

该页面的示例包括:

mongo server:27017/dbname --quiet my_commands.js
mongo test --eval "printjson(db.getCollectionNames())"

答案 5 :(得分:28)

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

function testMongoScript {
    mongo <<EOF
    use mydb
    db.leads.findOne()
    db.leads.find().count()
EOF
}

答案 6 :(得分:21)

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

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

答案 7 :(得分:18)

我使用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参数/变量,这不起作用。

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

#!/bin/env mongo
<some mongo stuff>

此解决方案存在一些问题:

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

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

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

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

    #!/bin/env mongo
    db = db.getSiblingDB('<db>');
    <your script>
    

    与生活中的任何事情一样,“有多种方法可以做到这一点!”

答案 8 :(得分:13)

这个怎么样:

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

答案 9 :(得分:13)

如果您启用了身份验证:

mongo -u username -p password --authenticationDatabase auth_db_name < your_script.js

答案 10 :(得分:12)

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

mongo <dbname> --eval "printjson(db.something.find())"

答案 11 :(得分:11)

创建脚本文件;写命令:

#!/bin/sh
mongo < file.js

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

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

答案 12 :(得分:7)

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

use someDb
db.someColl.find()

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

mongo < mongoCmds.js

相反,只有一个包含

的runMongoCmds.sh文件
printf "use someDb\ndb.someColl.find()" | mongo

Bash的printfecho强大得多,并且允许命令之间的\n强制它们在多行上。

答案 13 :(得分:4)

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

答案 14 :(得分:4)

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

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

答案 15 :(得分:3)

cmeans(X_train2.T, ...)

答案 16 :(得分:2)

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

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

cat file.sh | mongo <EXPECTED_COLLECTION>

答案 17 :(得分:1)

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

mongo < 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');

答案 18 :(得分:1)

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

echo $'use your_db\ndb.yourCollection.find()' | mongo

答案 19 :(得分:0)

wrote up从较大的Bash脚本中运行Mongo Shell脚本的各种选项

答案 20 :(得分:0)

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

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

cur = db.myCollection.find({});
while(cur.hasNext()) {
  printjson(cur.next());
}

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

答案 21 :(得分:0)

使用副本集时,必须在PRIMARY上完成写操作,因此我通常使用这样的语法,这样就不必弄清楚哪个主机是主机:

mongo -host myReplicaset/anyKnownReplica

相关问题