假设我在变量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")
...但是任何特殊字符搞砸了,我无法删除特殊字符。我该怎么办?
答案 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)
popen
和Shellwords.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