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

时间:2019-01-15 06:48:46

标签: ruby bash shell curl

我试图同时研究bash和ruby,并且试图传递一个包含来自ruby的JSON对象的变量,以便使用bash脚本进行打印。

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

所以在我的红宝石代码中,我有这个:

param = request.body
cmd = "ruby_to_bash #{param}"
exec cmd

在我的bash脚本中,我只是输出参数的值:

echo $1

例如,我有以下JSON:

{"first":"one","second":"two","third":"three"}

我的代码仅给我以下输出:

{first:

我想显示整个JSON对象。我怎样才能做到这一点?任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

bash和ruby都以一种特殊的方式处理双引号:双引号的字符串在传递给接收器之前先进行内插。我强烈建议您从头开始学习一些技巧,而不要因诱发的错误而使两者都没有取得零进展。

回答上述问题,因为红宝石和bash都将双引号视为内容定界符,所以在来回传递时必须转义双引号,而当内容中的内容已经解析后,则将其丢弃。

>

这将起作用:

exec %|ruby_to_bash #{param.gsub('"', '\"')}|

我使用%||作为字符串定界符,以避免与内部引号冲突。


边注:上面的内容不适用于包含空格的输入,但是我故意避免展示如何处理空格,因为它会导致死胡同;一旦处理了用单引号引起来的插值param周围的空格,我们就很容易被JSON对象中的内部单引号搞砸了。

上面的代码不是任何人都不能在生产中生产的。

答案 1 :(得分:1)

在这种情况下,我认为您最好的选择是完全不使用shell。

当你这样说的时候:

cmd = "ruby_to_bash #{param}"
exec cmd

您的exec调用正在调用一个解析cmd然后运行ruby_to_bash的shell,所以您要这样做:

  1. 构建命令行。
  2. /bin/sh替换当前进程。
  3. /bin/sh解析您应该混在一起的命令行。这是您需要担心引号和转义符才能越过外壳的地方。
  4. /bin/sh执行者的ruby_to_bash

您可以使用Kernel#exec的多参数形式来绕过整个问题:

  

exec(cmdname,arg1,...)
  命令名称和一个或多个参数(无外壳)

根本不用壳。如果您说:

exec 'ruby_to_bash', param

您将不需要外壳,param中的引号或空格对ruby_to_bash以外的任何人都无关紧要。