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

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

我尝试了以下方式test.sh

#!/bin/sh

mongo myDbName

db.mycollection.findOne()

show collections

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

然后 Build 了mongo连接,但是没有执行下一个命令

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

请帮我

回答(19)

2 years ago

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

mongo --eval "printjson(db.serverStatus())"

Please note: 如果你使用的是Mongo运算符,以$符号开头,你需要用单引号括起eval参数,以防止shell将运算符作为环境变量进行评估:

mongo --eval 'db.test.update({"name":"foo"},{$set:{"this":"that"}});'

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

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

2 years ago

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

这在Linux下适用于我:

mongo < script.js

2 years ago

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

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

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

2 years ago

还有一个official documentation页面 .

该页面的示例包括:

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

2 years ago

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

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

2 years ago

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

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

2 years ago

我使用了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>

与生活中的任何事物一样,“有不止一种方法可以做到!”

2 years ago

这个怎么样:

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

2 years ago

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

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

2 years ago

如果您启用了身份验证:

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

2 years ago

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

#!/bin/sh
mongo < file.js

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

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

2 years ago

谢谢 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 强制它们在多行上 .

2 years ago

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

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

2 years ago

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

2 years ago

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

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

cat file.sh | mongo <EXPECTED_COLLECTION>

2 years ago

mongo <<EOF
use <db_name>
db.getCollection("<collection_name>").find({})
EOF

2 years ago

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

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

2 years ago

最近从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');