1

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

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
4

2 回答 2

1

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

相反,如果您运行:

openssl genrsa -passout stdin ...

那么在这种情况下,它将读取标准输入,但它只需要输出文件密码一次。并且回答您提出的问题,是的,这是一个好方法,尽管它不是系统调用。

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

于 2009-09-22T17:51:41.997 回答
0

我发现使用“块”语法调用 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

这将适用于通过标准输入。但同时,也回馈了标准输出和标准错误。它避免了异常:

in 'write': closed stream (IOError)

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

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

于 2010-03-05T23:08:03.083 回答