Comment exécuter des commandes mongo via des scripts shell?
Je veux exécuter des commandes mongo dans un script shell.
J'ai essayé de manière suivante test.sh
#!/bin/sh
mongo myDbName
db.mycollection.findOne()
show collections
Quand j'exécute le script ci-dessus. /test.sh
Puis connexion mongo établie mais les commandes suivantes ne sont pas exécutées
Comment exécuter d'autres commandes via le script sh [test.sh] ?
S'il vous Plaît aidez-moi
19 réponses
Vous pouvez également évaluer une commande en utilisant l'indicateur --eval
, s'il ne s'agit que d'une seule commande.
mongo --eval "printjson(db.serverStatus())"
Remarque: Si vous utilisez des opérateurs Mongo, en commençant par un signe$, vous voudrez entourer l'argument eval de guillemets simples pour empêcher le shell d'évaluer l'opérateur en tant que variable d'environnement:
mongo --eval 'db.test.update({"name":"foo"},{$set:{"this":"that"}});'
Sinon vous pouvez voir quelque chose comme ceci:
mongo --eval "db.test.update({\"name\":\"foo\"},{$set:{\"this\":\"that\"}});"
> E QUERY SyntaxError: Unexpected token :
Mettez votre script mongo dans un fichier .js
.
Puis exécutez mongo < yourFile.js
Ex:
Démo.le fichier js / / a votre script
use sample //db name
show collections
Conservez ce fichier dans "c:\db-scripts"
Ensuite, dans l'invite cmd, allez à "c:\db-scripts"
C:\db-scripts>mongo < demo.js
Cela exécutera le code dans mongo et affichera la sortie
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>
Cela fonctionne pour moi sous Linux:
mongo < script.js
Mettre ça dans un fichier appelé test.js
:
db.mycollection.findOne()
db.getCollectionNames().forEach(function(collection) {
print(collection);
});
Puis exécutez-le avec mongo myDbName test.js
.
Il y a aussi une pagedocumentation officielle à ce sujet.
Voici quelques exemples de cette page:
mongo server:27017/dbname --quiet my_commands.js
mongo test --eval "printjson(db.getCollectionNames())"
Le script shell ci-dessous a également bien fonctionné pour moi... definite a dû utiliser la redirection qu'Antonin a mentionnée au début... cela m'a donné l'idée de tester le document ici.
function testMongoScript {
mongo <<EOF
use mydb
db.leads.findOne()
db.leads.find().count()
EOF
}
Dans ma configuration, je dois utiliser:
mongo --host="the.server.ip:port" databaseName theScript.js
Que diriez-vous de ceci:
echo "db.mycollection.findOne()" | mongo myDbName
echo "show collections" | mongo myDbName
Comme suggéré par theTuxRacer
, vous pouvez utiliser la commande eval, pour ceux qui la manquent comme je l'étais, vous pouvez également ajouter votre nom de base de données si vous n'essayez pas de préforme opération sur la base de données par défaut.
mongo <dbname> --eval "printjson(db.something.find())"
J'utilise la syntaxe" heredoc", que David Young mentionne. Mais il y a un hic:
#!/usr/bin/sh
mongo <db> <<EOF
db.<collection>.find({
fieldName: { $exists: true }
})
.forEach( printjson );
EOF
Ce qui précède ne fonctionnera pas, car l'expression "$exists " sera vue par le shell et remplacée par la valeur de la variable d'environnement nommée "exists."Ce qui, probablement, n'existe pas, donc après l'expansion du shell, il devient:
#!/usr/bin/sh
mongo <db> <<EOF
db.<collection>.find({
fieldName: { : true }
})
.forEach( printjson );
EOF
Pour le faire passer, vous avez deux options. L'un est moche, l'autre est plutôt gentil. Tout d'abord, le moche: échapper aux signes$:
#!/usr/bin/sh
mongo <db> <<EOF
db.<collection>.find({
fieldName: { \$exists: true }
})
.forEach( printjson );
EOF
Je ne le recommande pas, car il est facile d'oublier de s'échapper.
, L'autre option est d'échapper à l'EOF, comme ceci:
#!/usr/bin/sh
mongo <db> <<\EOF
db.<collection>.find({
fieldName: { $exists: true }
})
.forEach( printjson );
EOF
Maintenant, vous pouvez mettre tous les signes dollar que vous voulez dans votre heredoc, et le dollar signes sont ignorés. L'inconvénient: cela ne fonctionne pas si vous avez besoin de mettre des paramètres/variables shell dans votre script mongo.
Une autre option avec laquelle vous pouvez jouer est de jouer avec votre shebang. Par exemple,
#!/bin/env mongo
<some mongo stuff>
Il y a plusieurs problèmes avec cela solution:
Cela ne fonctionne que si vous essayez de faire un script shell mongo exécutable à partir de la ligne de commande. Vous ne pouvez pas mélanger les commandes shell régulières avec les commandes shell mongo. Et tout ce que vous enregistrez en le faisant n'est pas d'avoir à taper "mongo" sur la ligne de commande... (une raison suffisante, bien sûr)
Il fonctionne exactement comme "mongo " ce qui signifie qu'il ne vous permet pas d'utiliser la commande "use
".
J'ai essayé d'ajouter le nom de la base de données pour le shebang, que vous pensez fonctionnerait. Malheureusement, la façon dont le système traite la ligne shebang, tout après le premier espace est passé en tant que paramètre unique (comme s'il était entre guillemets) à la commande env, et env ne parvient pas à le trouver et à l'exécuter.
Au lieu de cela, vous devez intégrer le changement de base de données dans le script lui-même, comme ceci:
#!/bin/env mongo
db = db.getSiblingDB('<db>');
<your script>
Comme avec n'importe quoi dans la vie, "il y a plus d'une façon de le faire!"
Si l'authentification est activée:
mongo -u username -p password --authenticationDatabase auth_db_name < your_script.js
Merci printf
! Dans un environnement Linux, voici une meilleure façon d'avoir un seul fichier exécuter le spectacle. Disons que vous avez deux fichiers, mongoCmds.js
, avec plusieurs commandes:
use someDb
db.someColl.find()
Puis le fichier shell du pilote, runMongoCmds.sh
mongo < mongoCmds.js
Au lieu de cela, avoir un seul fichier, runMongoCmds.sh contenant
printf "use someDb\ndb.someColl.find()" | mongo
printf
de Bash est beaucoup plus robuste que echo
et permet aux \n
entre les commandes de les forcer sur plusieurs lignes.
Créer un fichier de script; écrire des commandes:
#!/bin/sh
mongo < file.js
Dans file.js
écrivez votre requête mongo:
db.collection.find({"myValue":null}).count();
mongo db_name --eval "db.user_info.find().forEach(function(o) {print(o._id);})"
--coque drapeau peut également être utilisé pour les fichiers javascript
mongo --shell /path/to/jsfile/test.js
Si vous voulez le gérer avec une ligne, c'est un moyen facile.
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
Dans mon cas, je peux facilement utiliser \n
comme séparateur pour la prochaine commande mongo que je veux exécuter puis les diriger vers mongo
echo $'use your_db\ndb.yourCollection.find()' | mongo
Récemment migré de mongodb vers Postgres. C'est ainsi que j'ai utilisé les scripts.
mongo < scripts.js > inserts.sql
Lisez le scripts.js
et la redirection de sortie vers inserts.sql
.
scripts.js
on dirait ceci
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
on dirait ceci
INSERT INTO table(a, b) VALUES('abc', 'Alice'), ('def', 'Bob'), ('ghi', 'Claire');