json - 制作一个既有效的 JSON 又转义 shell 的字符串

标签 json ruby linux bash shell

我有一个数组,我想将其转换为 JSON 字符串。其中一个元素有一个反引号。当我尝试在 shell 中运行命令时,这会导致错误:

data = [["305", "John Smith", "Amy Smith`", "10/11/2008", "Medical", {"page_count"=>4}]]
json_str = data.to_json.gsub('"','\"')
cmd = "node myscript.js #{json_str}"
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
  output = [stdout.read, stderr.read]
end 

Error retrieving data: sh: 1: Syntax error: EOF in backquote substitution

一个明显的解决方案是转义反引号:

json_str = data.to_json.gsub('"','\"').gsub('`','\\\`')

但我想转义所有可能引发 isuse 的特殊 shell 字符。 Ruby 的 shellescape 对字符串进行转义,以便可以在 Bourne shell 命令行中安全地使用它。这是一个例子:

argv = "It's better to give than to receive".shellescape
argv #=> "It\\'s\\ better\\ to\\ give\\ than\\ to\\ receive"

但看看当我将它应用于 JSON 字符串时会发生什么:

data = [["305", "John Smith", "Amy Smith`", "10/11/2008", "Medical", {"page_count"=>4}]]
data = data.to_json
 => "[[\"305\",\"John Smith\",\"Amy Smith`\",\"10/11/2008\",\"Medical\",{\"page_count\":4}]]"
data = data.to_json.shellescape

=> "\\"\\\\"\[\[\\\\\\\\"305\\\\\\\\",\\\\\\\\"约翰\史密斯\\\\\\\\",\\\\\\\\"艾米\史密斯\`\\\\\\\\",\\\\\\\\"10/11/2008\\\\\\\\",\\\\\\\\"医疗\\\\\\\\",\{\\\\\\\\"page_count\\\\\\\\": 4\}\]\]\\\\"\\""

显然,这会引发如下错误:

SyntaxError: Unexpected token \ in JSON at position 0

发生的情况是 shellescape 也会转义空格,因为 shell 需要转义空格。但是有空格是有效且必要的 JSON。那么,如何在不破坏 JSON 的情况下转义会导致我的命令出错的 shell 字符?

最佳答案

Shell 是给人类用的,不是给机器用的。让机器生成 shell 命令是一种代码味道,表明您在错误的层进行自动化。

跳过 shell,只需使用所需的参数运行您的程序:

data = [["305", "John Smith", "Amy Smith`", "10/11/2008", "Medical", {"page_count"=>4}]]
json_str = data.to_json
Open3.popen3("node", "myscript.js", json_str) do |stdin, stdout, stderr, wait_thr|
  output = [stdout.read, stderr.read]
end 

由于不涉及 shell ,因此不存在像逃避关心这样的人类愚蠢行为。

关于json - 制作一个既有效的 JSON 又转义 shell 的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53906007/

相关文章:

linux - x86-64 位汇编 Linux 输入

c - 域套接字 "sendto"遇到 "errno 111, connection refused"

python - 在 key ID上链接Json数据以创建全新的Json文件

javascript - jQuery .getJSON 返回数组变量和 json 数组操作

使用不同的键进行 JSON 解码

ruby-on-rails - Ruby on Rails 中 options.dup 的用途是什么?

linux - bash "&"不打印 "[1]+ Done "

javascript - 尝试基于 JSON 类型显示内容,没有带 Angular Controller

ruby - 查找连续的子串索引

ruby - 在 FreeBSD 上安装 gosu