web-dev-qa-db-ja.com

シェルスクリプトからmongoコマンドを実行する方法

シェルスクリプトでmongoコマンドを実行したい。スクリプトtest.sh内で:

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

./test.sh経由でこのスクリプトを実行すると、MongoDBへの接続は確立されますが、以下のコマンドは実行されません。

シェルスクリプトtest.shを通して他のコマンドを実行する方法?

336
StackOverFlow

--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 :
381
theTuxRacer

あなたの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>
285
Matt

これはLinuxの下で私のために働く:

mongo < script.js
92

これをtest.jsというファイルに入れます。

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

それからmongo myDbName test.jsを付けて実行します。

57
Theo

これについては 公式ドキュメント ページがあります。

そのページの例は次のとおりです。

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

下記のシェルスクリプトも私にとってはうまくいきました...最初はアントニンが言ったリダイレクトを使わなければなりませんでした。

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

私の設定では、私が使用しなければなりません:

mongo --Host="the.server.ip:port" databaseName theScript.js 
21
Ed Williams

David Youngが言及している "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

それを通過させるためには、2つの選択肢があります。 1つは醜いです、1つはかなりいいです。まず、醜いもの:$記号をエスケープします。

#!/usr/bin/sh

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

逃げるのを忘れがちなので、これはお勧めしません。

もう1つの選択肢は、次のようにEOFをエスケープすることです。

#!/usr/bin/sh

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

これで、必要なすべてのドル記号をヒアドキュメントに入れることができます。ドル記号は無視されます。欠点:mongoスクリプトにシェルのパラメータや変数を含める必要がある場合は、うまくいきません。

あなたが遊ぶことができるもう一つのオプションはあなたのShebangを台無しにすることです。例えば、

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

この解決策にはいくつかの問題があります。

  1. コマンドラインからmongo Shellスクリプトを実行可能にしようとしている場合にのみ機能します。通常のShellコマンドとmongo Shellコマンドを混在させることはできません。そして、そうすることで節約できるのは、コマンドラインで「mongo」と入力する必要がないということだけです...(もちろん、十分な理由)

  2. これは、 "mongo <some-js-file>"とまったく同じように機能します。つまり、 "use <db>"コマンドを使用することはできません。

データベース名をShebangに追加してみました。残念ながら、システムがShebang行を処理する方法では、最初のスペース以降のすべてが(引用符で囲まれたように)単一のパラメーターとしてenvコマンドに渡され、envはそれを見つけて実行することができません。

代わりに、次のようにデータベースの変更をスクリプト自体に埋め込む必要があります。

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

人生のあらゆるものと同様に、「それを行うには複数の方法があります!」

18
John Arrowwood

これはどう:

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

theTuxRacerで示唆されているように、 eval コマンドを使うことができます。私のように見つからなかった人のために、デフォルトのdbで操作しないのであればdb名を追加することもできます。

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

認証が有効になっている場合:

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

スクリプトファイルを作成します。コマンドを書く:

#!/bin/sh
mongo < file.js

file.jsにmongoクエリを書きます。

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

printfありがとうございます。 Linux環境では、1つのファイルだけでショーを実行するためのより良い方法があります。 2つのファイル、mongoCmds.jsが複数のコマンドであるとします。

use someDb
db.someColl.find()

そしてドライバのシェルファイルrunMongoCmds.sh

mongo < mongoCmds.js

代わりに、runMongoCmds.shを1つだけ含むファイルを用意してください。

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

Bashのprintfechoよりはるかに堅牢であり、コマンド間の\nを複数の行に強制することを可能にします。

7
tgoneil

- シェルフラグは、JavaScriptファイルにも使用できます。

 mongo --Shell /path/to/jsfile/test.js 
4
Jackson Harry
mongo db_name --eval "db.user_info.find().forEach(function(o) {print(o._id);})"
4
Talespin_Kit
mongo <<EOF
use <db_name>
db.getCollection("<collection_name>").find({})
EOF
3
Erdem ÖZDEMİR

1行で処理したい場合は簡単な方法です。

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

cat file.sh | mongo <EXPECTED_COLLECTION>
2
Erçin Akçay

私の場合は、次に実行したいmongoコマンドのセパレータとして\nを便利に使用してから、それらをmongoにパイプ処理することができます。

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

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

Mongo引数(--quiet、dbnameなど)を渡すことができるシングルシェルスクリプトソリューション:

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

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

-Sフラグは、すべてのプラットフォームで機能するとは限りません。

0
yǝsʞǝla

I 書きました 大きなBashスクリプトの中からMongoシェルスクリプトを実行するためのさまざまなオプション

0
PKD