代码之家  ›  专栏  ›  技术社区  ›  Daniel Viglione

使字符串同时成为有效的JSON和转义的shell

  •  1
  • Daniel Viglione  · 技术社区  · 7 年前

    我有一个数组,我想把它转换成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转义字符串,以便可以在BourneShell命令行中安全地使用它。下面是一个例子:

    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
    

    =>10月10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10月11日,2008年10月11日,10月11日,10月10月11日,10月10月11日,10月10月11日,10月11日,2008年10月11日,10月10月11日,10月11日,10月10日,10月11日,10月11日,10月10日,10月10日,10月10日,10月10日,10月11日,10月11日,10月10日,10月11日,10月11日,10月10日,10月10月10日,10月10日,10月10日,10月10日,10日,10月11日,10月11日,10月10日,10日,10月10日,10月10日,10日,10月11日,10月11日,来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自10月10月10月10月11日,10日,10月11日,来自来自来自来自来自来自来自来自“:4\\]\]\\\\\\\\\\\\\\\”“

    很明显,这会引发如下错误:

    SyntaxError: Unexpected token \ in JSON at position 0
    

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

    1 回复  |  直到 7 年前
        1
  •  4
  •   that other guy    7 年前

    贝壳是给人的,不是给机器的。让机器生成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 
    

    既然没有贝壳的牵连,也就没有逃避这样的愚蠢了。

    推荐文章