如何将json主体从ruby传递到bash脚本

如何将json主体从ruby传递到bash脚本,ruby,bash,shell,curl,Ruby,Bash,Shell,Curl,我试图研究bash和ruby,并试图通过bash脚本从ruby传递一个包含JSON对象的变量 我尝试将JSON对象存储在一个变量中,然后将该变量用作bash脚本的参数,但没有得到我想要的结果 因此,在我的ruby代码中,我有: param = request.body cmd = "ruby_to_bash #{param}" exec cmd 在我的bash脚本中,我只是简单地输出参数的值: echo $1 例如,我有一个JSON: {"first":"one","second":"two

我试图研究bash和ruby,并试图通过bash脚本从ruby传递一个包含JSON对象的变量

我尝试将JSON对象存储在一个变量中,然后将该变量用作bash脚本的参数,但没有得到我想要的结果

因此,在我的ruby代码中,我有:

param = request.body
cmd = "ruby_to_bash #{param}"
exec cmd
在我的bash脚本中,我只是简单地输出参数的值:

echo $1
例如,我有一个JSON:

{"first":"one","second":"two","third":"three"}
我的代码只提供以下输出:

{first:

我想显示整个JSON对象。我该怎么做?任何形式的帮助都将不胜感激。

bash和ruby都以一种特殊的方式处理双引号:双引号字符串在传递给接收者之前进行插值。我强烈建议你从一开始就学习一点,而不是因为诱发错误而在这两方面都做零进展

在回答上述问题时,在来回传递时必须转义双引号,因为ruby和bash都将双引号视为内容分隔符,而在结果字符串中已经解析了内容时将其丢弃

这将有助于:

exec %|ruby_to_bash #{param.gsub('"', '\"')}|
我使用
%
作为字符串分隔符,以避免与内部引号冲突


旁注:上述内容不适用于包含空格的输入,但我故意避免说明如何处理空格,因为它会导致死胡同;一旦用单引号处理了插值的
param
周围的空格,我们很容易在JSON对象中使用内部单引号等等


上面的代码是不应该有人在生产中产生的。

我认为你最好的选择是,像往常一样,在这种情况下,根本不涉及外壳

当你这么说的时候:

cmd = "ruby_to_bash #{param}"
exec cmd
您的
exec
调用正在调用一个shell,该shell解析
cmd
,然后运行
ruby\u to\u bash
,因此您要执行以下操作:

  • 构建一个命令行
  • 将当前进程替换为
    /bin/sh
  • /bin/sh
    解析应该混合在一起的命令行。这就是你需要担心引用和逃避的地方
  • /bin/sh
    exec的
    ruby\u to\u bash
  • 您可以使用以下多参数形式绕过整个问题:

    exec(cmdname,arg1,…)
    命令名和一个或多个参数(无shell)

    这根本不需要一个外壳。如果你说:

    exec 'ruby_to_bash', param
    

    您不会涉及shell,
    param
    中的引号或空格对任何人来说都无关紧要,除了
    ruby\u to_bash

    hello@Aleksei,非常感谢您的回复,但是它仍然没有输出整个json对象。它只是从我以前的输出中添加了一个双引号,请确保它是这样的。您必须检查您为我们提供的输入。如果您的输入更复杂,并且包含空格(很可能是这种情况),则在将整个字符串传递给shell之前,应该使用单引号将其括起来。@Noel:您没有显示
    ruby_to_bash
    ,但对于您的具体示例字符串,我想
    cmd=“ruby_to_bash'{param}”将起作用。当然,它不会在一般情况下(对于每个JSON)字符串都起作用,而构建命令行并使用
    exec
    运行它的整个想法是有缺陷的。如果您将参数单独传递给脚本,则会更好;有关exec方法,请参阅文档。@user1934428还有一个命令数量级的子shell,它比用
    内核#exec
    替换当前进程要好;否则他就不会使用
    exec
    。事实上,如果将控件传递给脚本是要执行的最后一个操作,我不明白为什么他不应该按自己的方式执行。