Ruby open4r多系统调用提示

时间:2009-09-22 01:55:18

标签: ruby system openssl open4

我正在尝试编写一个使用open4生成密钥对的lib,这是处理多个提示的系统调用的最佳方法吗?

require 'rubygems'
require 'open4'
Open4::popen4("sh") do |pid, stdin, stdout, stderr|
  stdin.puts "openssl genrsa -des3 -out tmp_priv.pem 2048" 
  stdin.puts "1234" 
  stdin.puts "1234"
  stdin.close
end
Open4::popen4("sh") do |pid, stdin, stdout, stderr|
  stdin.puts "openssl rsa -in tmp_priv.pem -out tmp_public.pem -outform PEM -pubout"
  stdin.puts "1234"
  stdin.close
end
Open4::popen4("sh") do |pid, stdin, stdout, stderr|
  stdin.puts "cat tmp_priv.pem  tmp_public.pem >> tmp_keypair.pem" 
  stdin.close
end

2 个答案:

答案 0 :(得分:1)

我不确定你的例子会做你想做的事。如果按照您的问题运行,openssl将打开/dev/tty,并且尽管有管道,它最终会提示用户。它不会看到1234

如果您改为运行:

openssl genrsa -passout stdin ...

然后在那种情况下它将读取stdin但它只需要输出文件密码一次。并回答你提出的问题,是的,这是一个好方法,虽然它不是系统调用。

在类Unix系统上,首先需要伪造程序输入也是非常罕见的。您可能需要重新阅读openssl(1ssl)genrsa(1ssl)手册页;他们会注意到各种不同的密码来源选项。

答案 1 :(得分:0)

我发现使用“block”语法调用popen4是行不通的。

但我发现的作品是这样做的:

harp: > cat sample/simple.rb
require "open4"

pid, stdin, stdout, stderr = Open4:open4 "sh"

stdin.puts "echo 42.out"
stdin.puts "echo 42.err 1>&2"
stdin.close

ignored, status = Process::waitpid2 pid

puts "pid : #{ pid }"
puts "stdout : #{ stdout.read.strip }"
puts "stderr : #{ stderr.read.strip }"
puts "status : #{ status.inspect }"
puts "exitstatus : #{ status.exitstatus }"


harp: > ruby sample/simple.rb
pid : 17273
stdout : 42.out
stderr : 42.err
status : #<Process::Status: pid=17273,exited(0)>
exitstatus : 0

通过stdin会有效。但与此同时,还要回馈stdout和stderr。它避免了例外:

in 'write': closed stream (IOError)

太。所以这似乎是使用popen4的最佳方式。

有关其他示例,请参阅自述文件: http://github.com/ahoward/open4