我试图同时研究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对象。我怎样才能做到这一点?任何帮助将不胜感激。
答案 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,所以您要这样做:
/bin/sh
替换当前进程。/bin/sh
解析您应该混在一起的命令行。这是您需要担心引号和转义符才能越过外壳的地方。/bin/sh
执行者的ruby_to_bash
。您可以使用Kernel#exec
的多参数形式来绕过整个问题:
exec(cmdname,arg1,...)
命令名称和一个或多个参数(无外壳)
根本不用壳。如果您说:
exec 'ruby_to_bash', param
您将不需要外壳,param
中的引号或空格对ruby_to_bash
以外的任何人都无关紧要。