Ich verwende die "heredoc"-Syntax, die David Young erwähnt hat. Aber es gibt einen Haken:
#!/usr/bin/sh
mongo <db> <<EOF
db.<collection>.find({
fieldName: { $exists: true }
})
.forEach( printjson );
EOF
Das obige funktioniert NICHT, weil die Phrase "$exists" von der Shell erkannt und durch den Wert der Umgebungsvariablen "exists" ersetzt wird. Die wahrscheinlich nicht existiert, so dass sie nach der Shell-Expansion zu "$exists" wird:
#!/usr/bin/sh
mongo <db> <<EOF
db.<collection>.find({
fieldName: { : true }
})
.forEach( printjson );
EOF
Um sie durchzulassen, haben Sie zwei Möglichkeiten. Die eine ist hässlich, die andere ist ganz nett. Erstens, die hässliche: die $-Zeichen entkommen:
#!/usr/bin/sh
mongo <db> <<EOF
db.<collection>.find({
fieldName: { \$exists: true }
})
.forEach( printjson );
EOF
Ich empfehle dies NICHT, denn man kann leicht vergessen zu fliehen.
Die andere Möglichkeit besteht darin, das EOF zu umgehen, etwa so:
#!/usr/bin/sh
mongo <db> <<\EOF
db.<collection>.find({
fieldName: { $exists: true }
})
.forEach( printjson );
EOF
Jetzt können Sie so viele Dollarzeichen in Ihr Heredoc eingeben, wie Sie wollen, und die Dollarzeichen werden ignoriert. Der Nachteil: Das funktioniert nicht, wenn Sie Shell-Parameter/Variablen in Ihr Mongo-Skript einfügen müssen.
Eine weitere Option, die Sie ausprobieren können, ist das Durcheinanderbringen Ihrer Ausrüstung. Zum Beispiel,
#!/bin/env mongo
<some mongo stuff>
Bei dieser Lösung gibt es mehrere Probleme:
-
Es funktioniert nur, wenn Sie versuchen, ein Mongo-Shell-Skript über die Befehlszeile ausführbar zu machen. Sie können keine normalen Shell-Befehle mit Mongo-Shell-Befehlen mischen. Und alles, was Sie dadurch sparen, ist, dass Sie "mongo" nicht in die Kommandozeile eingeben müssen... (Grund genug, natürlich)
-
Es funktioniert genau wie "mongo <some-js-file>", d.h. Sie können den Befehl "use <db>" nicht verwenden.
Ich habe versucht, den Namen der Datenbank in das Verzeichnis einzufügen, was eigentlich funktionieren sollte. Leider verarbeitet das System die shebang-Zeile so, dass alles nach dem ersten Leerzeichen als einzelner Parameter (wie in Anführungszeichen) an den env-Befehl übergeben wird und env ihn nicht finden und ausführen kann.
Stattdessen müssen Sie die Datenbankänderung in das Skript selbst einbetten, etwa so:
#!/bin/env mongo
db = db.getSiblingDB('<db>');
<your script>
Wie bei allem im Leben gilt auch hier: "Es gibt mehr als einen Weg, es zu tun!"