bash 脚本 - 无法设置值中包含双引号的变量
bash script - unable to set variable with double quotes in value
需要帮助来修复此 bash 脚本以设置一个包含双引号的值的变量。由于我的值 foo
和 bar
未按需要用双引号引起来,因此我以某种方式错误地定义了它。
到目前为止我的脚本:
#!/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='"''"'
(单引号,双引号,单引号,
变量,
单引号,双引号,单引号)
需要帮助来修复此 bash 脚本以设置一个包含双引号的值的变量。由于我的值 foo
和 bar
未按需要用双引号引起来,因此我以某种方式错误地定义了它。
到目前为止我的脚本:
#!/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='"''"'
(单引号,双引号,单引号,
变量,
单引号,双引号,单引号)