如何将Bash变量传递给JSON

3

我正在尝试编写一个示例脚本,其中我正在生成类似于“student-101...student-160”的名称。我需要发布JSON数据,但当我这样做时,我会得到一个JSON解析错误。

这是我的脚本:

name="student-10"

for i in {1..1}
do
    r_name=$name$i
    echo $r_name
    curl -i -H 'Authorization: token <token>' -d '{"name": $r_name, "private": true}' "<URL>" >> create_repos_1.txt
    echo created $r_name
done

我总是遇到“解析JSON出现问题”的错误。我尝试过各种引号等组合,但好像都不起作用!我做错了什么?

顺便提一下,如果您曾经开始以这种方式推送“真实”名称(从数据库、Web表单中),那么请一定要转义它们。 - Ruud Helderman
使用1值序列{1..1}的目的是什么? - RomanPerekhrest
@RuudHelderman 非常好的建议!我会记住的。 - Saturnian
@RomanPerekhrest 哦,目前只有一次推送。稍后我会增加到60! - Saturnian
3个回答

7

首先,你的name属性是一个字符串,在你的json中需要加上双引号。

其次,如果使用单引号,bash将不会进行变量扩展:它不会用变量内容替换$r_name(有关更多信息,请参见在bash shell脚本中命令内部单引号中的变量扩展)。

总之,请使用:

-d '{"name": "'"$r_name"'", "private": true}'

2
你现在有 $r_name 未加引号,因此当 shell 展开它时,它将受到单词拆分和路径名扩展的影响。你想要 -d '{"name": "'"$r_name"'", "private": true}' - glenn jackman
这对我起作用了。然而,我无法理解引号之间的区别 :( - Saturnian

5
另一个选项是使用 printf 来创建数据字符串:
printf -v data '{"name": "%s", "private": true}' "$r_name"
curl -i -H 'Authorization: token <token>' -d "$data" "$url" >> create_repos_1.txt

2

不要使用 jq(或类似工具)来使用变量输入构建正确引用的 JSON。

name="student-10"

for i in {1..1}
do
    r_name=$name$i
    jq -n --arg r_name "$r_name" '{name: $r_name, private: true}' |
      curl -i -H 'Authorization: token <token>' -d @- "<URL>" >> create_repos_1.txt
    echo created $r_name
done
@-参数告诉curl从标准输入中读取数据(通过来自jq的管道)用于-d

类似"{\"name\": \"$r_name\", \"private\": true}"的东西可能有效,但它很丑陋,并且如果r_name包含任何需要在生成的JSON中进行引用的字符,例如双引号或ASCII控制字符,则也会失败。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接