首页 文章

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

提问于
浏览 1669
301

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

我尝试了以下方式test.sh

#!/bin/sh

mongo myDbName

db.mycollection.findOne()

show collections

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

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

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

请帮我

19 回答

  • 349

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

    file.sh --> db.EXPECTED_COLLECTION.remove("_id":1234)
    
    cat file.sh | mongo <EXPECTED_COLLECTION>
    
  • 268

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

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

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

    #!/bin/sh
    mongo < file.js
    

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    mongo <dbname> --eval "printjson(db.something.find())"
    
  • 8
    mongo db_name --eval "db.user_info.find().forEach(function(o) {print(o._id);})"
    
  • 7

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

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

    这个怎么样:

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

    如果您启用了身份验证:

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

    这在Linux下适用于我:

    mongo < script.js
    
  • 2

    还有一个official documentation页面 .

    该页面的示例包括:

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

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

  • -1

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

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

相关问题