我想在shell脚本中执行mongo命令,例如在脚本test.sh :
#!/bin/sh
mongo myDbName
db.mycollection.findOne()
show collections
当我通过./test.sh执行此脚本时,将建立与MongoDB的连接,但不会执行以下命令。
如何通过shell脚本test.sh执行其他命令?
#1楼
也有关于此的官方文档页面。
该页面上的示例包括:
mongo server:27017/dbname --quiet my_commands.js
mongo test --eval "printjson(db.getCollectionNames())"
#2楼
我使用David Young提到的“ heredoc”语法。 但是有一个问题:
#!/usr/bin/sh
mongo <
db..find({
fieldName: { $exists: true }
})
.forEach( printjson );
EOF
上面的命令不起作用,因为外壳程序会看到短语“ $ exists”,并用名为“ exists”的环境变量的值代替。 可能不存在,因此在shell扩展后,它变为:
#!/usr/bin/sh
mongo <
db..find({
fieldName: { : true }
})
.forEach( printjson );
EOF
为了使它通过,您有两个选择。 一个很丑,一个很不错。 一,丑陋的一面:逃脱$符号:
#!/usr/bin/sh
mongo <
db..find({
fieldName: { \$exists: true }
})
.forEach( printjson );
EOF
我不建议这样做,因为很容易忘记逃脱。
另一个选择是逃避EOF,如下所示:
#!/usr/bin/sh
mongo <
db..find({
fieldName: { $exists: true }
})
.forEach( printjson );
EOF
现在,您可以将所有所需的美元符号放入heredoc中,而美元符号将被忽略。 不利的一面:如果您需要在mongo脚本中放入shell参数/变量,那将不起作用。
您可以使用的另一种选择是弄乱您的shebang。 例如,
#!/bin/env mongo
此解决方案存在几个问题:
仅当您尝试从命令行使mongo shell脚本可执行时,它才有效。 您不能将常规的shell命令与mongo shell命令混合使用。 这样,您节省的所有事情都不必在命令行上键入“ mongo” ...(当然,理由足够多)
它的功能与“ mongo ”完全相同,这意味着它不允许您使用“ use ”命令。
我尝试过将数据库名称添加到shebang中,您认为这会起作用。 不幸的是,系统处理shebang行的方式是,第一个空格之后的所有内容都作为单个参数(如被引用)传递给env命令,而env找不到并运行它。
相反,您必须将数据库更改嵌入脚本本身中,如下所示:
#!/bin/env mongo
db = db.getSiblingDB('');
就像生活中的一切一样,“有不止一种方法可以做到这一点!”
#3楼
这个怎么样:
echo "db.mycollection.findOne()" | mongo myDbName
echo "show collections" | mongo myDbName
#4楼
--shell标志也可用于javascript文件
mongo --shell /path/to/jsfile/test.js
#5楼
谢谢printf ! 在Linux环境中,这是一种只运行一个文件的更好方法。 假设您有两个带有多个命令的文件mongoCmds.js :
use someDb
db.someColl.find()
然后是驱动程序外壳文件runMongoCmds.sh
mongo < mongoCmds.js
相反,只有一个文件,其中包含runMongoCmds.sh
printf "use someDb\ndb.someColl.find()" | mongo
Bash的printf比echo更为健壮,并且允许在命令之间使用\\n将它们强制在多行上。