我有一个脚本,它使用Docker env vars在启动时配置json文件。该函数在相同的JQ命令中使用相同的ENV var两次,并且在第一个位置,整数保持为set,在第二行中,JQ从数字中减去13(WTF?)。有谁能解释一下?更重要的是,我如何防止这种情况发生。
注意:为了使配置有效,第二个实例必须是不带引号的整数。测试显示引用整数会导致预期输出,但配置无效。
Env Var
DISCORD_CHANNEL=448887356515418113
Bash功能:
function updateDiscordConfig {
echo "Setting Discord configuration..."
jq ".discord |= . + {\"token\":\"${DISCORD_TOKEN}\"} | .discord.channels.channels |= . + {\"${DISCORD_CHANNEL}\": {}} | .minecraft.dimensions.generic |= . + {\"discordChannel\": [${DISCORD_CHANNEL}]}" ${DISCORD_SRCCONFIG} | sponge ${DISCORD_DESTCONFIG}
}
输出:
// First output
"channels": {
"448887356515418113": {}
}
// Second output
"discordChannel": [
448887356515418100
],
更新:我已使用sed替换了第二个实例更新:
function updateDiscordConfig {
echo "Setting Discord configuration..."
jq ".discord |= . + {\"token\":\"${DISCORD_TOKEN}\"} | .discord.channels.channels |= . + {\"${DISCORD_CHANNEL}\": {}}" ${DISCORD_SRCCONFIG} | sponge ${DISCORD_DESTCONFIG}
sed -i "/discordChannel/c\ \"discordChannel\" : [${DISCORD_CHANNEL}]," ${DISCORD_DESTCONFIG}
}
答案 0 :(得分:2)
不幸的是,你遇到了jq的一个主要限制 - 数值精度。 jq将JSON数字映射到IEEE 754 64位数字。这将在jq FAQ"注意事项"
中讨论如果您不想使用其他编程语言, 你可以使用" BigInt" jq的模块 - https://gist.github.com/pkoppstein/d06a123f30c033195841
但是,这适用于字符串表示,因此它可能比您的用例更有麻烦。
如果您只需要添加,可以使用此jq def:
# The args should be strings representing non-negative integers
# without a leading "+":
def add(num1;num2):
if (num1|length) < (num2|length) then add(num2;num1)
else (num1 | explode | map(.-48) | reverse) as $a1
| (num2 | explode | map(.-48) | reverse) as $a2
| reduce range(0; num1|length) as $ix
($a2; # result
( $a1[$ix] + .[$ix] ) as $r
| if $r > 9 # carrying
then
.[$ix + 1] = ($r / 10 | floor) +
(if $ix + 1 >= length then 0 else .[$ix + 1] end )
| .[$ix] = $r - ( $r / 10 | floor ) * 10
else
.[$ix] = $r
end )
| reverse | map(.+48) | implode
end ;
使用它的一种方法是将它复制到jq库中的文件(比如add.jq)(例如〜/ .jq /)
并使用include
包含它,例如如下所示:
jq -n 'include "add";
add("448887356515418113";"448887356515418113")'
"897774713030836226"
答案 1 :(得分:2)
通常,出于这个原因,您不应该在JSON中对大型数字字符串使用数字类型。但是,如果Discord需要一个整数 - 如果它能够从配置中获取正确的非基础值,而它用于解析它 - 那么你需要另一种方法。也许Python?
function updateDiscordConfig {
echo "Setting Discord configuration..."
python -c "import json, sys; conf = json.load(sys.stdin); conf['discord']['token']='$DISCORD_TOKEN'; conf['discord']['channels']['channels']='$DISCORD_CHANNEL';conf['minecraft']['dimensions']['generic']['discordChannel']=[$DISCORD_CHANNEL];print(json.dumps(conf));" ${DISCORD_SRCCONFIG} | sponge ${DISCORD_DESTCONFIG}
}