在MongoDB查询中使用shell变量

3

有没有办法在MongoDB查询中使用shell变量?

例如,我有以下代码:

#!/usr/bin/env bash

mongo --eval "use cdt_db; db.users.update({username:'${USER}'}, {'\$set':{roles:['Admin']}});"

我尝试了单引号和双引号,但出现了以下错误:

MongoDB shell version v3.4.9
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.9
2017-10-09T13:53:51.747-0700 E QUERY    [thread1] SyntaxError: missing ; before statement @(shell eval):1:4

$set 不应该加引号吗?最安全的方法是将表达式放在单引号下,并将其与变量值连接起来:mongo cdt_db --eval 'db.users.update({username:"'"$USER"'"}, {$set:{roles:["Admin"]}});' - randomir
1
是的,那似乎有效。如果您能详细解释并回答问题,我至少会点赞。 - Alexander Mills
很高兴听到这个消息。我会写下来的。 - randomir
不确定原因是什么...而且,使用单引号时,在 $set 中不需要转义 $。 - Alexander Mills
1
让我纠正/修改自己。$USER 经历了 shell 参数扩展(除非使用单引号,否则总是这样)。因此,如果 USER='*',那么 "$USER" 将扩展为 *。但是,如果您不将其双引号括起来,则它也会通过路径名扩展(globbing),因此 $USER 将扩展为 file1 file2 ...。如果您编写 cmd 'str' $USER,则变量将被路径名扩展(cmd 接收到 str file1 file2 ...),但是如果您编写 cmd 'str'$USER,则变量不会被路径名扩展(除非有空格),但是 USER 中的空格不会被保留!因此,安全的做法是编写 cmd 'str'"$USER" - randomir
显示剩余3条评论
1个回答

3
从shell的角度来看,你的查询没问题。变量USER已正确展开,并且$set中的$已被正确转义以防止shell参数展开。
问题在于查询的use <dbname>部分。根据文档

不能在JavaScript文件中使用任何shell助手(例如use <dbname>show dbs等),因为它们不是有效的JavaScript。

相反,你可以使用JavaScript等效方法:
db = db.getSiblingDB('<dbname>')

或者更好的方法是,通过命令行参数指定数据库的名称:
mongo dbname --eval 'query'

已解决,您的查询看起来像:

mongo cdt_db --eval "db.users.update({username:'${USER}'}, {\$set:{roles:['Admin']}});"

为了方便(少转义),有时您也可以考虑使用单引号,并连接展开的变量(在双引号下):

mongo cdt_db --eval 'db.users.update({username:"'"${USER}"'"}, {$set:{roles:["Admin"]}});'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接