使用变量向AWS IoT发布温度值时遇JSON格式错误求助
问题根源:Shell单引号的变量替换限制
这个问题其实是Shell里单引号与双引号的行为差异坑到你了——你写的'{"state": {"desired": {"temperature": $DATA }}}'用了单引号包裹JSON内容,而Shell会把单引号里的所有内容当作纯文本,不会解析其中的$DATA变量。所以实际发送给AWS的JSON是{"state": {"desired": {"temperature": $DATA }}},这显然不是有效的JSON($DATA不是合法的数字或字符串格式),自然会触发JSON格式错误。
正确的解决方案
下面提供几种靠谱的写法,你可以选最顺手的:
1. 混合引号+转义(最直接的修改)
把包含变量的JSON部分改成双引号,同时转义JSON内部的双引号(避免Shell解析),主题部分用单引号包裹保留$符号:
#!/bin/bash # 先验证传入的参数是整数(可选但推荐) if ! [[ "$1" =~ ^[0-9]+$ ]]; then echo "错误:请传入整数类型的温度值" exit 1 fi DATA="$1" mosquitto_pub -t '$aws/things/my-xxxx/shadow/update' -m "{\"state\": {\"desired\": {\"temperature\": $DATA}}}" -q 1
2. 使用Here-string构造JSON(更易读)
如果JSON结构复杂,转义双引号会很麻烦,用Here-string可以直接写原生JSON:
#!/bin/bash if ! [[ "$1" =~ ^[0-9]+$ ]]; then echo "错误:请传入整数类型的温度值" exit 1 fi DATA="$1" mosquitto_pub -t '$aws/things/my-xxxx/shadow/update' -m @- -q 1 <<EOF {"state": {"desired": {"temperature": $DATA}}} EOF
这里的@-表示从标准输入读取消息内容,而<<EOF和EOF之间的内容会作为标准输入传入。
3. 用printf构造JSON(最安全)
用printf格式化字符串来生成JSON,能更好地控制变量替换,避免格式错误:
#!/bin/bash if ! [[ "$1" =~ ^[0-9]+$ ]]; then echo "错误:请传入整数类型的温度值" exit 1 fi JSON=$(printf '{"state": {"desired": {"temperature": %d}}}' "$1") mosquitto_pub -t '$aws/things/my-xxxx/shadow/update' -m "$JSON" -q 1
%d是整数格式化符,确保传入的参数会被当作整数插入到JSON中,避免意外的字符串格式问题。
额外提醒
- 主题里的
$aws必须保留原样,所以用单引号包裹主题'$aws/things/...'是最稳妥的方式,避免Shell把$aws当作变量解析(如果你的环境里刚好定义了aws变量,会导致主题错误)。 - 一定要验证输入参数是整数,不然如果传入非数字内容,生成的JSON依然会格式错误。
内容的提问来源于stack exchange,提问作者DDBE
相关产品推荐
相关产品推荐

