Escape JSON in Mix shell echo 命令

Escape JSON in Mix shell echo command

我有一个类似的代码。我希望它回显一个有效的 JSON 并在属性上加上引号,以便它可以通过管道传输到另一个命令。但是在回声的同时,它正在撕掉所有引号。

def test_function() do
  map = %{
    "key1" => 12,
    "key2" => "value1",
  }

  json = Poison.encode!(map)
  IO.inspect(json)

  Mix.Shell.cmd(
    "echo #{json}",
    fn x -> IO.puts(x) end
  )
end

预计

{"key2":"value1","key1":12}

实际

{key2:value1,key1:12}

当 Elixir IO 已经绑定到 STDOUT 时,您不需要依赖 OS echo 命令。我认为您可能会在这里遇到麻烦,因为您正在将 IO.inspect 的结果和 IO.puts 的结果(包装在系统的 echo 命令中)发送到 STDOUT,所以它至少使事情加倍,这令人困惑,但它也可能无效。

这对我有用,给定一个包含

的简单github.json文件
{
    "sha": "d25341478381063d1c76e81b3a52e0592a7c997f",
    "commit": {
        "author": {
            "name": "Stephen Dolan",
            "email": "mu@netsoc.tcd.ie",
            "date": "2013-06-22T16:30:59Z"
        }
    },
    "url": "https://api.github.com/repos/stedolan/jq/commits/d25341478381063d1c76e81b3a52e0592a7c997f"
}

parse.exs 脚本一起存储,其中包含以下内容:

contents = File.read!("github.json")
map = Jason.decode!(contents)

json_str = Jason.encode!(map)
IO.puts(json_str)

此解码和编码证明这是有效的(替换 Poison 或任何所需的内容)。

现在,我可以通过 mix run parse.exs 运行 以下命令,我看到了预期的结果。我也可以按预期通过管道输出,例如到 jq:

❯ mix run parse.exs | jq '.sha'
"d25341478381063d1c76e81b3a52e0592a7c997f"

我不得不在单引号中引用 JSON 字符串

Mix.Shell.cmd(
  "echo '#{json}'",
  fn x -> IO.puts(x) end
)

Ref