Shell脚本中执行Mongo查询出现SyntaxError语法错误问题求助
问题根因
- 你使用无引号包裹的
<<EOF定义Here Document时,Shell会先对内容中所有$开头的标识符做变量展开、命令替换预处理,再将处理后的内容传给Mongo进程 - 你的Mongo代码中
$object_id、$nin、$set这些本应由Mongo解析的标识符会被Shell优先识别为自身变量,如果Shell中未定义对应变量,会被替换为空字符串,直接破坏Mongo语法结构,触发你遇到的语法报错 - 直接在Mongo Shell中执行无异常,是因为不存在Shell预处理步骤,
$开头的符号会被Mongo正确识别为查询操作符或内部变量 - 你初步判断的
db.getCollection相关命令问题属于误判,和该语法无关
解决方案
根据你是否需要在Mongo脚本中注入Shell变量,选择对应方案:
方案1:不需要注入Shell变量(推荐,无需修改Mongo代码)
给EOF加单引号,完全禁用Shell的预处理逻辑,所有内容原样传递给Mongo,修改后的Shell代码如下:
mongo jenkinsdb <<'EOF' ids_to_exclude = db.history.find({projectId: $object_id._id.str}, {_id:1}).sort({"_id":-1}).limit(2).toArray() var array = new Array() ids_to_exclude.forEach(function(myDoc){array.push(myDoc._id);}) array db.getCollection('history').updateMany({ _id:{$nin:array}},{$set:{backupPath:undefined}}) exit EOF
方案2:需要注入Shell变量(比如$object_id是你Shell脚本中定义的变量,需要传入Mongo)
保留无引号的EOF,将Mongo语法中所有原生$操作符前加反斜杠转义,避免被Shell替换,示例如下(假设你Shell中已经提前定义了object_id变量):
mongo jenkinsdb <<EOF ids_to_exclude = db.history.find({projectId: ${object_id}._id.str}, {_id:1}).sort({"_id":-1}).limit(2).toArray() var array = new Array() ids_to_exclude.forEach(function(myDoc){array.push(myDoc._id);}) array db.getCollection('history').updateMany({ _id:{\$nin:array}},{\$set:{backupPath:undefined}}) exit EOF
验证方法
修改前可以先将mongo jenkinsdb替换为echo,打印Here Document的输出内容,确认语法和你直接在Mongo Shell中执行的代码一致后再替换回Mongo命令执行。
内容的提问来源于stack exchange,提问作者Youssef Boudaya
相关产品推荐
相关产品推荐

