Ruby中的进程替换(不是命令替换)

时间:2014-10-07 22:09:07

标签: ruby

在bash,zsh,ksh88,ksh93和类似的shell中,可以简单地生成一个文件名(适用于平台,实现为/dev/fd条目或命名管道)一段代码在子shell中执行。

我有兴趣在Ruby解释器中执行相同的操作 - 使用其中一个参数执行子进程文件名,当读取时,将流式传输在当前Ruby解释器中运行的代码的输出或子进程相同。

内容对安全性敏感,因此写入临时文件并不理想。


bash中的等效代码:

./run-program --password-file=<(printf '%s' "$password")

...运行时,将(在Linux或其他具有/dev/fd/的平台上)调用类似的内容:

./run-program --password-file=/dev/fd/5

...其中/dev/fd/5可以从中读取(只需一次,作为流),以检索展开$password的结果。


在Ruby中实现相同调用约定的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

IO.popen与shell中的>()<()做同样的事情 - 它会创建一个未命名的单向管道,您可以读取或写入。

fd=IO.popen("echo hi") #"r"--reading by default
fd.read 
   #=>"hi\n"
   #Read from the file object
#OR access via the filesystem representation of the filedescriptor
File.read("/dev/fd/#{fd.fileno}")
   #This is just how linux works (note in Linux, each process sees `/dev/fd/` differently--it's actually the open filedescriptors a process has)

基本上,我认为你会想要使用unamed管道。另一个常见的模式是使用IO.pipe创建管道对,拆分子进程,并且因为分叉共享文件描述符,您的子进程和父进程将基本上通过您可以拥有的管道对连接想。

答案 1 :(得分:0)

基本答案可能是用Ruby的Kernel#spawn方法构建一些东西。这将允许您启动另一个进程并控制子进程用于输入和输出的文件对象。

请注意,处理此问题可能会非常棘手;有一个好的Unix应用程序编程参考将很有帮助。 Ruby实际上只是为一些低级Unix / C API提供了一个薄的包装。