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

hsgswve4  于 12个月前  发布在  Ruby
关注(0)|答案(3)|浏览(104)

在bash、zsh、ksh 88、ksh 93和类似的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中实现相同调用约定的最佳方法是什么?

jm2pwxwz

jm2pwxwz1#

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创建管道对,分叉一个子进程,由于分叉共享文件描述符,您的子进程和父进程基本上将通过该管道对连接,您可以拥有任意多个管道对。

46scxncf

46scxncf2#

基本的答案可能是从Ruby的Kernel#spawn方法中构建一些东西。这将允许您启动另一个进程,并控制子进程使用哪些文件对象进行输入和输出。
请注意,处理这可能是棘手的;手边有一本好Unix应用程序编程参考书是很有帮助的。Ruby实际上只是在一些低级Unix/C API周围放置了一个薄薄的 Package 。

mi7gmzs6

mi7gmzs63#

您可以使用IO.popen将密码传递给cat程序。

# open a pipe to `cat`
# the argument is a one-element array to force it
# to run the program directly instead of through a shell
fd = IO.popen(['cat'], 'r+')
# write the password through the pipe
fd.print('password')
# finish writing
fd.close_write

fd.read #=> 'password'
# or
File.read("/dev/fd/#{fd.fileno}") #=> 'password'

fd.close

相关问题