在Go语言中,可以将JSON对象作为命令行标志的值传递吗?

huangapple go评论81阅读模式
英文:

Can I pass a json object as value for a cli flag in go?

问题

我正在使用urfave/cli来编写我的Go程序,我想要一个CLI标志,用于读取像这样的JSON值:

{"name":"foo","surname":"var"}

我目前将该变量读取为cli.StringFlag,它返回一个字符串。然后,我计划使用json.Unmarshal对其进行解析,但是它不起作用。问题在于CLI库返回的字符串是这样的:

[{name foo} {surname var}]

这不再是一个JSON。

有没有办法实现这个?请注意,如果它返回一个简单的映射,那也可以。

英文:

I am using urfave/cli for my go program and I would like to have a cli flag that reads a json value like this one:

{"name":"foo","surname":"var"}

I am currently reading that variable as a cli.StringFlag which returns a string. Then, I was planning to json.Unmarshall it but it does not work. The problem is that the returned string by the cli library is like this:

[{name foo} {surname var}]

which is not a json anymore.

Is there a way to achieve this? Note that if it returned a simple map, that would work too

答案1

得分: 1

对于Linux系统,请尝试使用shell转义来传递参数:

#!/bin/bash

echo "{\"name\":\"foo\",\"surname\":\"var\"}"

在Go程序中,只需将此字符串参数进行编组(marshal)。

英文:

for Linux, try to pass the paramaters with shell escape

#!/bin/bash

echo "{\"name\":\"foo\",\"surname\":\"var\"}"

in go program, just marshal this string parameter

答案2

得分: 1

问题是,shell(bash、ksh、csh、zsh等)将以下内容解释为一系列的“裸字”和“带引号的字”标记:

标记类型
裸字 {
带引号的字 name
裸字 :
带引号的字 foo
裸字 ,
带引号的字 surname
裸字 :
带引号的字 var
裸字 }

事实上,逗号(,)是一个用于算术运算的shell操作符,它基本上被丢弃了(至少在我使用的zsh中)。

然后将所有内容拼接在一起,得到

name:foo surname:var

你可以通过打开你的shell并执行以下命令来看到这个过程:

echo {"name":"foo","surname":"var"}

然而,如果你使用单引号(')引用你的JSON文档:

echo ''{"name":"foo","surname":"var"}''

你将得到你所期望的结果:

{"name":"foo","surname":"var"}

然而,请注意,如果你的JSON文档中的文本包含一个字面上的撇号/单引号('),那么这种方法将失败,所以你需要用\,来替换JSON文档中的所有这样的出现以进行转义。

英文:

The issue is that the shell (bash, ksh, csh, zsh, ...) interprets

{"name":"foo","surname":"var"}

as a sequence of bareword and quoted word tokens:

Token Type Value
bareword {
quoted word name
bareword :
quoted word foo
bareword ,
quoted word surname
bareword :
quoted word var
bare word }

As it happens, a comma (,) is a shell operator, used for arithmetic, and that essentially gets discarded (at least in zsh, what I use).

The whole is then spliced together to get

name:foo surname:var

You can see this in action by opening your shell and executing the command

echo {"name":"foo","surname":"var"}

If, however, you quote your JSON document with single quotes ('):

echo '{"name":"foo","surname":"var"}'

You'll get what you might expect:

{"name":"foo","surname":"var"}

Note, however, that this will fail if the text in your JSON document contains a literal apostrophe/single quote (', U+0027), so you'd want to replace all such occurrences within the JSON document with \, to escape them.

huangapple
  • 本文由 发表于 2022年10月13日 23:27:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/74058299.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定