bash 脚本 - 无法设置值中包含双引号的变量

bash script - unable to set variable with double quotes in value

需要帮助来修复此 bash 脚本以设置一个包含双引号的值的变量。由于我的值 foobar 未按需要用双引号引起来,因此我以某种方式错误地定义了它。

到目前为止我的脚本:

#!/usr/local/bin/bash
set -e
set -x

host='127.0.0.1'
db='mydev'
_account="foo"
_profile="bar"
_version=
_mongo=$(which mongo);

exp="db.profile_versions_20170420.find({account:${_account}, profile:${_profile}, version:${_version}}).pretty();";
${_mongo} ${host}/${db} --eval "$exp"

set +x

输出显示:

+ host=127.0.0.1
+ db=mydev
+ _account=foo
+ _profile=bar
+ _version=201704112004
++ which mongo
+ _mongo=/usr/local/bin/mongo
+ exp='db.profile_versions_20170420.find({account:foo, profile:bar, version:201704112004}).pretty();'
+ /usr/local/bin/mongo 127.0.0.1/mydev --eval 'db.profile_versions_20170420.find({account:foo, profile:bar, version:201704112004}).pretty();'
MongoDB shell version: 3.2.4
connecting to: 127.0.0.1/mydev
2017-04-22T15:32:55.012-0700 E QUERY    [thread1] ReferenceError: foo is not defined :
@(shell eval):1:36

我需要的是account:"foo"profile:"bar"用双引号括起来。

当您需要在双引号字符串中使用双引号时,请使用反斜杠将其转义:

$ foo="acount:\"foo\"" sh -c 'echo $foo'
  acount:"foo"

在bash(以及其他POSIX shell)中,以下两种状态是等价的:

_account=foo
_account="foo"

您想做的是保留引文,因此您可以执行以下操作:

_account='"foo"'

由于您在这里所做的部分工作是形成 JSON,请考虑使用 jq——这将 保证 它的结构是正确的,不管值是多少。

host='127.0.0.1'
db='mydev'
_account="foo"
_profile="bar"
_version=

json=$(jq -n --arg account "$_account" --arg profile "$_profile" --arg version "$_version" \
  '{$account, $profile, version: $version | tonumber}')

exp="db.profile_versions_20170420.find($json).pretty();"
mongo "${host}/${db}" --eval "$exp"

这使得 jq 负责在适当的地方添加文字引号,并将避免尝试注入攻击(例如,通过传入 </code> 的版本包含 <code>1, "other_argument": "malicious_value" 之类的内容),通过用 \" 替换字符串中的任何文字 ";带有 \n 等的字面换行符 - 或者,使用 | tonumber 转换时,任何非数字值都会完全失败。


请注意,上面的某些语法需要 jq 1.5——如果您使用的是 1.4 或更早版本,您将需要编写 {account: $account, profile: $profile} 而不是能够使用键名编写 {$account, $profile}从变量名推断。

我需要引用变量中已有的内容并将其粘贴到变量中。扩展 ,我发现这行得通:

VAR='"''"'

(单引号,双引号,单引号,
变量,
单引号,双引号,单引号)