如何将变量传递给ruby中的system()调用?

时间:2012-05-24 06:58:56

标签: ruby unix command-line command-line-interface

假设我在变量some_var中有一堆文本,几乎可以是任何内容。

some_var = "Hello, I'm a \"fancy\" variable | with a pipe, double- and single-quotes (terminated and unterminated), and more."

我们还要说,在CLI Ruby应用程序中,我想允许用户将该文本传递给任何Unix命令。我允许他们输入类似some_var | espeak -a 200 -v en-us的内容,其中管道右侧的命令是系统上安装的任何unix CLI工具。

我们还要说我已经将变量选择和管道分离出来了,所以我确切地知道管道后面的命令是100%。 (在这种情况下,我想将变量的内容传递给espeak -a 200 -v en-us。)

我该怎么做?我认为我不能使用反引号方法或%x[]字面值。我试过以下......

system("echo '#{some_var}' | espeak -a 200 -v en-us")

...但是任何特殊字符搞砸了,我无法删除特殊字符。我该怎么办?

5 个答案:

答案 0 :(得分:7)

除了popen,您还可以查看Shellwords.escape

puts Shellwords.escape("I'm quoting many different \"''' quotes")
=> I\'m\ quoting\ many\ different\ \"\'\'\'\ quotes

这将为您引用特殊字符(bash兼容):

system("echo '#{Shellwords.escape(some_var)}' | ....")

http://www.ruby-doc.org/stdlib-1.9.3/libdoc/shellwords/rdoc/Shellwords.html

答案 1 :(得分:4)

哦,快乐的注射。您正在寻找 IO.popen

IO.popen('grep ba', 'r+') {|f| # don't forget 'r+'
  f.puts("foo\nbar\nbaz\n") # you can also use #write
  f.close_write
  f.read # get the data from the pipe
}
# => "bar\nbaz\n"

答案 2 :(得分:2)

popenShellwords.escape是很好的解决方案,但系统已经内置了数组语法转义

system('argument', 'argument2', 'argument3')

例如

2.1.2 :002 > abc = "freeky\nbreak"
# "freeky\nbreak" 

2.1.2 :003 > system("echo #{abc}")  #this is bad
freeky
# => true 

2.1.2 :004 > system("echo",abc)     # this is proper way
freeky
break
# => true 

答案 3 :(得分:0)

啊哈!我找到了。根据{{​​3}},Kernel#open实际上可以打开一个进程并将数据传递给它,而不仅仅是文件!

some_var = "Hello, I'm a \"fancy\" variable | with a pipe, double- and single-quotes (terminated and unterminated), and more."
# some_command = "espeak -a 200 -v en-us" # also works
some_command = "cat"

cmd = "|" + some_command
open(cmd, 'w+') do | subprocess |
  subprocess.write(some_var)
  subprocess.close_write
  subprocess.read.split("\n").each do |output|
    puts "[RUBY] Output: #{output}"
  end
end

答案 4 :(得分:-1)

将varible传递给系统调用的示例:

irb(main):019:0> b = "test string string string"
=> "test string string string"
irb(main):020:0> system("echo " + "#{b}" + "|" + "awk '{print $2}'")
string
=> true
  

@Kerrick如果您有未确定的引号,仍会出现大量语法错误,   括号等

也许:

some_var = "'Hello, Im a \"fancy\" variable | with a pipe, double- and single-quotes (terminated and unterminated), and more.'"
    => "'Hello, Im a \"fancy\" variable | with a pipe, double- and single-quotes (terminated and unterminated), and more.'"

irb(main):020:0> system("echo " + "#{some_var}" + "|" + "awk '{print $2}'")Im
        => true