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

发布于 2024-10-15 01:50:58 字数 307 浏览 13 评论 0原文

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

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

当我通过 ./test.sh 执行此脚本时,那么与MongoDB的连接就建立了,但是下面的命令没有执行。

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

I want to execute mongo commands in shell script, e.g. in a script test.sh:

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

When I execute this script via ./test.sh, then the connection to MongoDB is established, but the following commands are not executed.

How to execute other commands through shell script test.sh?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(22

水中月 2024-10-22 01:50:58

如果命令只是单个命令,您还可以使用 --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 :

You can also evaluate a command using the --eval flag, if it is just a single command.

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

Please note: if you are using Mongo operators, starting with a $ sign, you'll want to surround the eval argument in single quotes to keep the shell from evaluating the operator as an environment variable:

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

Otherwise you may see something like this:

mongo --eval "db.test.update({\"name\":\"foo\"},{$set:{\"this\":\"that\"}});"
> E QUERY    SyntaxError: Unexpected token :
谁对谁错谁最难过 2024-10-22 01:50:58

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

Put your mongo script into a .js file.

Then execute mongo < yourFile.js

Ex:

demo.js //file has your script

use sample  //db name
show collections

keep this file in "c:\db-scripts"

Then in cmd prompt go to "c:\db-scripts"

C:\db-scripts>mongo < demo.js

This will execute the code in mongo and shows the output

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>
凉城已无爱 2024-10-22 01:50:58

这在 Linux 下适用于我:

mongo < script.js

对于较新版本的 mongodb

mongosh < script.js

This works for me under Linux:

mongo < script.js

For newer version of mongodb

mongosh < script.js
温柔一刀 2024-10-22 01:50:58

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

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

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

Put this in a file called test.js:

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

then run it with mongo myDbName test.js.

甚是思念 2024-10-22 01:50:58

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

该页面的示例包括:

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

There is an official documentation page about this as well.

Examples from that page include:

mongo server:27017/dbname --quiet my_commands.js
mongo test --eval "printjson(db.getCollectionNames())"
鱼窥荷 2024-10-22 01:50:58

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

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

The shell script below also worked nicely for me... definite had to use the redirect that Antonin mentioned at first... that gave me the idea to test the here document.

function testMongoScript {
    mongo <<EOF
    use mydb
    db.leads.findOne()
    db.leads.find().count()
EOF
}
一人独醉 2024-10-22 01:50:58

如果您启用了身份验证:

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

对于较新版本

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

In case you have authentication enabled:

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

For newer version

mongosh -u username -p password --authenticationDatabase auth_db_name < your_script.js
又怨 2024-10-22 01:50:58

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

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

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

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

此解决方案有几个问题:

  1. 它仅在您尝试从命令行使 mongo shell 脚本可执行时才有效。您不能将常规 shell 命令与 mongo shell 命令混合使用。这样做所节省的只是不必在命令行中输入“mongo”...(当然,这是足够的理由)

  2. 它的功能与“mongo”完全相同这意味着它不允许您使用“use”命令。

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

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

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

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

I use the "heredoc" syntax, which David Young mentions. But there is a catch:

#!/usr/bin/sh

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

The above will NOT work, because the phrase "$exists" will be seen by the shell and substituted with the value of the environment variable named "exists." Which, likely, doesn't exist, so after shell expansion, it becomes:

#!/usr/bin/sh

mongo <db> <<EOF
db.<collection>.find({
  fieldName: { : true }
})
.forEach( printjson );
EOF

In order to have it pass through you have two options. One is ugly, one is quite nice. First, the ugly one: escape the $ signs:

#!/usr/bin/sh

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

I do NOT recommend this, because it is easy to forget to escape.

The other option is to escape the EOF, like this:

#!/usr/bin/sh

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

Now, you can put all the dollar signs you want in your heredoc, and the dollar signs are ignored. The down side: That doesn't work if you need to put shell parameters/variables in your mongo script.

Another option you can play with is to mess with your shebang. For example,

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

There are several problems with this solution:

  1. It only works if you are trying to make a mongo shell script executable from the command line. You can't mix regular shell commands with mongo shell commands. And all you save by doing so is not having to type "mongo" on the command line... (reason enough, of course)

  2. It functions exactly like "mongo <some-js-file>" which means it does not let you use the "use <db>" command.

I have tried adding the database name to the shebang, which you would think would work. Unfortunately, the way the system processes the shebang line, everything after the first space is passed as a single parameter (as if quoted) to the env command, and env fails to find and run it.

Instead, you have to embed the database change within the script itself, like so:

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

As with anything in life, "there is more than one way to do it!"

潜移默化 2024-10-22 01:50:58

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

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

对于较新版本的 mongodb

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

In my setup I have to use:

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

For newer version of mongodb

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

戏舞 2024-10-22 01:50:58

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

echo 

较新版本的 mongodb

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

较新版本的 mongodb


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

较新版本的 mongodb

In my case, I can conveniently use \n as separator for the next mongo command I want to execute then pipe them to mongo

echo 

Newer version of mongodb

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

Newer version of mongodb


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

Newer version of mongodb

北陌 2024-10-22 01:50:58

这个怎么样:

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

How about this:

echo "db.mycollection.findOne()" | mongo myDbName
echo "show collections" | mongo myDbName
掩耳倾听 2024-10-22 01:50:58

创建脚本文件;写入命令:

#!/bin/sh
mongo < file.js

对于较新版本
蒙戈什file.js

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

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

Create a script file; write commands:

#!/bin/sh
mongo < file.js

For newer versions
mongosh < file.js

In file.js write your mongo query:

db.collection.find({"myValue":null}).count();
书间行客 2024-10-22 01:50:58

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

use someDb
db.someColl.find()

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

mongo < mongoCmds.js

较新版本的 mongodb

mongosh < mongoCmds.js

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

printf "use someDb\ndb.someColl.find()" | mongo

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

Thank you printf! In a Linux environment, here's a better way to have only one file run the show. Say you have two files, mongoCmds.js with multiple commands:

use someDb
db.someColl.find()

and then the driver shell file, runMongoCmds.sh

mongo < mongoCmds.js

Newer version of mongodb

mongosh < mongoCmds.js

Instead, have just one file, runMongoCmds.sh containing

printf "use someDb\ndb.someColl.find()" | mongo

Bash's printf is much more robust than echo and allows for the \n between commands to force them on multiple lines.

甚是思念 2024-10-22 01:50:58

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

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

较新版本的 mongodb

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

As suggested by theTuxRacer, you can use the eval command, for those who are missing it like I was, you can also add in your db name if you are not trying to preform operation on the default db.

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

Newer version of mongodb

mongosh <dbname> --eval "printjson(db.something.find())"
苏别ゝ 2024-10-22 01:50:58
mongo <<EOF
use <db_name>
db.getCollection("<collection_name>").find({})
EOF
mongo <<EOF
use <db_name>
db.getCollection("<collection_name>").find({})
EOF
画尸师 2024-10-22 01:50:58

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

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

--shell flag can also be used for javascript files

 mongo --shell /path/to/jsfile/test.js 
他是夢罘是命 2024-10-22 01:50:58
mongo db_name --eval "db.user_info.find().forEach(function(o) {print(o._id);})"
mongo db_name --eval "db.user_info.find().forEach(function(o) {print(o._id);})"
日记撕了你也走了 2024-10-22 01:50:58

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

Recently migrated from mongodb to Postgres. This is how I used the scripts.

mongo < scripts.js > inserts.sql

Read the scripts.js and output redirect to inserts.sql.

scripts.js looks like this

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 looks like this

INSERT INTO table(a, b) VALUES('abc', 'Alice'), ('def', 'Bob'), ('ghi', 'Claire');
爱殇璃 2024-10-22 01:50:58

如果您想用一行来处理它,这是一种简单的方法。

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

cat file.sh | mongo <EXPECTED_COLLECTION>

If you want to handle it with one line it's an easy way.

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

cat file.sh | mongo <EXPECTED_COLLECTION>
迷途知返 2024-10-22 01:50:58

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

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

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

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

Single shell script solution with ability to pass mongo arguments (--quiet, dbname, etc):

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

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

The -S flag might not work on all platforms.

沉睡月亮 2024-10-22 01:50:58

随着 2022 年版本 6 的发布,旧版 mongo shell 已从 MongoDB 中删除。

有一种使用新 shell 执行 shell 脚本的新方法,mongosh

来自 有关编写脚本的 shell 文档

  • 您可以使用 mongosh 从命令执行脚本行而不进入 mongosh 控制台
  • 要指定文件名,请使用 --file 或 -f 参数来指定文件名
  • 您可能还需要指定连接信息

例如:

mongosh dbName --eval "db.users.find()"

The legacy mongo shell has been removed from MongoDB with the version 6 release in 2022

There is a new way to execute shell scripts using the new shell, mongosh

From the shell documentation on writing scripts:

  • You can use mongosh to execute a script from the command line without entering the mongosh console
  • To specify the filename, use the --file or -f parameter to specify the filename
  • You may also need to specify connection information

For example:

mongosh dbName --eval "db.users.find()"
格子衫的從容 2024-10-22 01:50:58

使用副本集时,写入必须在 PRIMARY 上完成,因此我通常使用这样的语法,这样可以避免必须弄清楚哪个主机是主主机:

mongo -host myReplicaset/anyKnownReplica

When using a replicaset, writes must be done on the PRIMARY, so I usually use syntax like this which avoids having to figure out which host is the master:

mongo -host myReplicaset/anyKnownReplica

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文