如何在 bash 中使用带有嵌入引号的位置参数?
How to use positional argument with embed quotes in bash?
我正在尝试创建一个 bash 脚本来自动配置一些与 letsencrypt 相关的东西。
我必须编辑的文件是 json 所以我只需要使用 jq
来编辑它并通过脚本的位置参数将网站名称传递给它,但我不能'获取传递到 json 文本中的位置参数。
我正在尝试执行如下操作:
JSON=`jq '. + { "ssl_certificate": "/etc/letsencrypt/live//fullchain.pem" }' <<< echo site_config.json`
JSON=`jq '. + { "ssl_certificate_key": "/etc/letsencrypt/live//fullchain.pem" }' <<< ${JSON}`
echo -e "$JSON" > site_config.json
其中第二个位置参数(</code>)包含需要在 json 文件中设置的域名。</p>
<p>如何做到这一点?</p>
<p>原文json:</p>
<pre><code>{
"key1":"value1",
"key2":"value2"
}
求购json:
{
"key1":"value1",
"key2":"value2",
"ssl_certificate": "/etc/letsencrypt/live/somesite.com/fullchain.pem",
"ssl_certificate_key": "/etc/letsencrypt/live/somesite.com/fullchain.pem"
}
1。 bash
下的字符串构造
我使用printf
和八进制表示嵌套引号和双引号:
printf -v JSON 'Some "double quoted: 7%s7"' "Any string"
echo "$JSON"
Some "double quoted: 'Any string'"
2。使用 jq
,严格回答已编辑的问题:
myFunc() {
local file="" site="" JSON
printf -v JSON '. + {
"ssl_certificate": "/etc/letsencrypt/live/%s/fullchain.pem",
"ssl_certificate_key": "/etc/letsencrypt/live/%s/fullchain.pem"
}' "$site" "$site"
jq "$JSON" <"$file"
}
然后运行:
myFunc site_config.json test.com
{
"key1": "value1",
"key2": "value2",
"ssl_certificate": "/etc/letsencrypt/live/test.com/fullchain.pem",
"ssl_certificate_key": "/etc/letsencrypt/live/test.com/fullchain.pem"
}
myFunc site_config.json test.com >site_config.temp && mv site_config.{temp,conf}
甚至:
myFunc <(
printf '{ "key1":"value1","key2":"value2","comment":"Let7s doit1" }'
) test.com
将呈现:
{
"key1": "value1",
"key2": "value2",
"comment": "Let's doit!",
"ssl_certificate": "/etc/letsencrypt/live/test.com/fullchain.pem",
"ssl_certificate_key": "/etc/letsencrypt/live/test.com/fullchain.pem"
}
2b。用 jq
的 --arg
选项写得更好:
感谢!
我使用 bash 数组来存储带有引号、空格和其他特殊字符的字符串。这更具可读性,因为不需要转义 end-of-line(反斜杠)并允许注释:
myFunc() {
local file="" site=""
local JSON=(
--arg ssl_certificate "/etc/letsencrypt/live/$site/fullchain.pem"
--arg ssl_certificate_key "/etc/letsencrypt/live/$site/fullchain.pem"
'. + {$ssl_certificate, $ssl_certificate_key}' # this syntax
# do offer two advantages: 1: no backslashes and 2: permit comments.
)
jq "${JSON[@]}" <"$file"
}
3。内联编辑功能
用于编辑小脚本。我更喜欢使用 cp -a
来保存
属性并确保在更换前有效操作。
如果您打算使用它,主要用于替换,您可以在函数中添加替换:
myFunc() {
local REPLACE=false
[ "" = "-r" ] && REPLACE=true && shift
local file="" site=""
local JSON=( --arg ssl_certificate "/etc/letsencrypt/live/$site/fullchain.pem"
--arg ssl_certificate_key "/etc/letsencrypt/live/$site/fullchain.pem"
'. + {$ssl_certificate, $ssl_certificate_key}' )
if $REPLACE;then
cp -a "$file" "${file}.temp"
exec {out}>"${file}.temp"
else
exec {out}>&1
fi
jq "${JSON[@]}" <"$file" >&$out &&
$REPLACE && mv "${file}.temp" "$file"
exec {out}>&-
}
然后要修改文件而不是将结果转储到终端,您必须添加 -r
选项:
myFunc -r site_config.json test.org
I cannot get the positional argument passed into the json text.
一般来说,到目前为止最好的方法是使用 jq 的 --arg and/or --argjson command-line 选项。这是安全的,在当前情况下意味着您只需调用 jq 一次。例如:
< site_config.json \
jq --arg sslc "/etc/letsencrypt/live//fullchain.pem" \
--arg sslck "/etc/letsencrypt/live//fullchain.pem" '
. + {ssl_certificate: $sslc, ssl_certificate_key: $sslck }'
一旦您确定一切正常,请随意使用 moreutils 的 sponge
:-)
一个DRY-er解决方案
感谢 jq 的简洁便利功能,可以写更多 DRY-ly:
< site_config.json \
jq --arg ssl_certificate "/etc/letsencrypt/live//fullchain.pem" \
--arg ssl_certificate_key "/etc/letsencrypt/live//fullchain.pem" '
. + {$ssl_certificate, $ssl_certificate_key }'
``
我正在尝试创建一个 bash 脚本来自动配置一些与 letsencrypt 相关的东西。
我必须编辑的文件是 json 所以我只需要使用 jq
来编辑它并通过脚本的位置参数将网站名称传递给它,但我不能'获取传递到 json 文本中的位置参数。
我正在尝试执行如下操作:
JSON=`jq '. + { "ssl_certificate": "/etc/letsencrypt/live//fullchain.pem" }' <<< echo site_config.json`
JSON=`jq '. + { "ssl_certificate_key": "/etc/letsencrypt/live//fullchain.pem" }' <<< ${JSON}`
echo -e "$JSON" > site_config.json
其中第二个位置参数(</code>)包含需要在 json 文件中设置的域名。</p>
<p>如何做到这一点?</p>
<p>原文json:</p>
<pre><code>{
"key1":"value1",
"key2":"value2"
}
求购json:
{
"key1":"value1",
"key2":"value2",
"ssl_certificate": "/etc/letsencrypt/live/somesite.com/fullchain.pem",
"ssl_certificate_key": "/etc/letsencrypt/live/somesite.com/fullchain.pem"
}
1。 bash
下的字符串构造我使用printf
和八进制表示嵌套引号和双引号:
printf -v JSON 'Some "double quoted: 7%s7"' "Any string"
echo "$JSON"
Some "double quoted: 'Any string'"
2。使用 jq
,严格回答已编辑的问题:
myFunc() {
local file="" site="" JSON
printf -v JSON '. + {
"ssl_certificate": "/etc/letsencrypt/live/%s/fullchain.pem",
"ssl_certificate_key": "/etc/letsencrypt/live/%s/fullchain.pem"
}' "$site" "$site"
jq "$JSON" <"$file"
}
然后运行:
myFunc site_config.json test.com
{
"key1": "value1",
"key2": "value2",
"ssl_certificate": "/etc/letsencrypt/live/test.com/fullchain.pem",
"ssl_certificate_key": "/etc/letsencrypt/live/test.com/fullchain.pem"
}
myFunc site_config.json test.com >site_config.temp && mv site_config.{temp,conf}
甚至:
myFunc <(
printf '{ "key1":"value1","key2":"value2","comment":"Let7s doit1" }'
) test.com
将呈现:
{
"key1": "value1",
"key2": "value2",
"comment": "Let's doit!",
"ssl_certificate": "/etc/letsencrypt/live/test.com/fullchain.pem",
"ssl_certificate_key": "/etc/letsencrypt/live/test.com/fullchain.pem"
}
2b。用 jq
的 --arg
选项写得更好:
感谢
我使用 bash 数组来存储带有引号、空格和其他特殊字符的字符串。这更具可读性,因为不需要转义 end-of-line(反斜杠)并允许注释:
myFunc() {
local file="" site=""
local JSON=(
--arg ssl_certificate "/etc/letsencrypt/live/$site/fullchain.pem"
--arg ssl_certificate_key "/etc/letsencrypt/live/$site/fullchain.pem"
'. + {$ssl_certificate, $ssl_certificate_key}' # this syntax
# do offer two advantages: 1: no backslashes and 2: permit comments.
)
jq "${JSON[@]}" <"$file"
}
3。内联编辑功能
用于编辑小脚本。我更喜欢使用 cp -a
来保存
属性并确保在更换前有效操作。
如果您打算使用它,主要用于替换,您可以在函数中添加替换:
myFunc() {
local REPLACE=false
[ "" = "-r" ] && REPLACE=true && shift
local file="" site=""
local JSON=( --arg ssl_certificate "/etc/letsencrypt/live/$site/fullchain.pem"
--arg ssl_certificate_key "/etc/letsencrypt/live/$site/fullchain.pem"
'. + {$ssl_certificate, $ssl_certificate_key}' )
if $REPLACE;then
cp -a "$file" "${file}.temp"
exec {out}>"${file}.temp"
else
exec {out}>&1
fi
jq "${JSON[@]}" <"$file" >&$out &&
$REPLACE && mv "${file}.temp" "$file"
exec {out}>&-
}
然后要修改文件而不是将结果转储到终端,您必须添加 -r
选项:
myFunc -r site_config.json test.org
I cannot get the positional argument passed into the json text.
一般来说,到目前为止最好的方法是使用 jq 的 --arg and/or --argjson command-line 选项。这是安全的,在当前情况下意味着您只需调用 jq 一次。例如:
< site_config.json \
jq --arg sslc "/etc/letsencrypt/live//fullchain.pem" \
--arg sslck "/etc/letsencrypt/live//fullchain.pem" '
. + {ssl_certificate: $sslc, ssl_certificate_key: $sslck }'
一旦您确定一切正常,请随意使用 moreutils 的 sponge
:-)
一个DRY-er解决方案
感谢 jq 的简洁便利功能,可以写更多 DRY-ly:
< site_config.json \
jq --arg ssl_certificate "/etc/letsencrypt/live//fullchain.pem" \
--arg ssl_certificate_key "/etc/letsencrypt/live//fullchain.pem" '
. + {$ssl_certificate, $ssl_certificate_key }'
``