Как выполнить команды mongo через сценарии оболочки?


Я хочу выполнить команды mongo в сценарии оболочки.

я попробовал следующим образом test.sh

#!/bin/sh

mongo myDbName

db.mycollection.findOne()

show collections

когда я выполняю выше скрипт ./test.sh

затем монго соединение установлено, но следующие команды не выполняются

Как выполнить другие команды через SH script [test.sh] ?

пожалуйста, помогите мне

19 294

19 ответов:

вы также можете оценить команды с помощью --eval флаг, если это всего лишь одной команды.

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

обратите внимание: если вы используете операторы Mongo, начиная со знака$, вы хотите окружить аргумент eval в одинарных кавычках, чтобы оболочка не оценивала оператор как переменную среды:

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 :

поместите свой сценарий монго в .

выполнить mongo < yourFile.js

пример:

демо.js / / файл имеет свой скрипт

use sample  //db name
show collections

держите этот файл в "c:\db-scripts"

затем в командной строке перейдите к "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>

это работает для меня под Linux:

mongo < script.js

положить это в файл под названием test.js:

db.mycollection.findOne()
db.getCollectionNames().forEach(function(collection) {
  print(collection);
});
С mongo myDbName test.js.

есть официальная документация страница об этом.

Примеры с этой страницы включают в себя:

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

сценарий оболочки ниже также работал хорошо для меня... определенно пришлось использовать перенаправление, которое Антонин упомянул сначала... это дало мне идею проверить здесь документ.

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

в моей настройке я должен использовать:

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

Как насчет этого:

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

Как было предложено theTuxRacer можно использовать eval команда, для тех, кто не хватает его, как я был, вы также можете добавить в свое имя БД, если вы не пытаетесь предварительно сформировать операцию на БД по умолчанию.

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

Я использую синтаксис "heredoc", который упоминает Дэвид Янг. Но есть подвох:

#!/usr/bin/sh

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

вышеописанное не будет работать, потому что фраза "$exists" будет видна оболочкой и заменена значением переменной среды с именем "exists."Который, скорее всего, не существует, поэтому после расширения оболочки он становится:

#!/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.

другой вариант, с которым вы можете играть, - это возиться с вашим shebang. Для например,

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

есть несколько проблем с этим решением:

  1. он работает только в том случае, если вы пытаетесь сделать сценарий оболочки mongo исполняемым из командной строки. Вы не можете смешивать обычные команды оболочки с командами оболочки mongo. И все, что вы сохраните, сделав это, не нужно вводить "mongo" в командной строке... (достаточная причина, конечно)

  2. он функционирует точно так же, как " mongo ", что означает, что это не так позвольте вам использовать команду " use ".

Я попытался добавить имя базы данных в shebang, который, как вы думаете, будет работать. К сожалению, то, как система обрабатывает строку shebang, все после первого пробела передается как один параметр (как будто в кавычках) команде env, и env не может найти и запустить его.

вместо этого вы должны встроить изменение базы данных в сам скрипт, например:

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

как с все в жизни, " есть более чем один способ сделать это!"

если у вас включена аутентификация:

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

спасибо printf! В среде Linux, вот лучший способ иметь только один файл запустить шоу. Скажем, у вас есть два файла, mongoCmds.js С несколькими командами:

use someDb
db.someColl.find()

а затем файл оболочки драйвера,runMongoCmds.sh

mongo < mongoCmds.js

вместо этого, есть только один файл, runMongoCmds.sh содержащий

printf "use someDb\ndb.someColl.find()" | mongo
Баша!--3--> гораздо надежнее, чем echo и \n между командами, чтобы заставить их на несколько строк.

создать файл скрипта; написать команды:

#!/bin/sh
mongo < file.js

на file.js напишите свой запрос монго:

db.collection.find({"myValue":null}).count();
mongo db_name --eval "db.user_info.find().forEach(function(o) {print(o._id);})"

--флаг оболочки также может быть использован для файлов JavaScript

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

Если вы хотите справиться с это простой способ.

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

cat file.sh | mongo <EXPECTED_COLLECTION>
mongo <<EOF
use <db_name>
db.getCollection("<collection_name>").find({})
EOF

В моем случае, я могу удобно использовать \n в качестве разделителя для следующей команды mongo я хочу выполнить, а затем передать их в mongo

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

недавно мигрировал из 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');