R中的读写管道()通信

时间:2011-03-18 16:53:35

标签: r ipc pipe

大多数语言都支持双向进程通信。例如,在Python中,我可以(邋)地做:

>>> from subprocess import *
>>> p = Popen('nslookup', stdin=PIPE, stdout=PIPE)
>>> p_stdin, p_stdout = p.communicate("www.google.com")
>>> print p_stdin
Server:     ...

在R中,无论我是用“r +”还是“w +”打开我的管道,我都只能走一条路。此外,即使我通过R -f ...R < ...运行脚本,在实际的控制台stdin / stdout中也会出现奇怪的行为。

我的问题归结为以下内容 - 是否有可能(无需编写C方法!)在R中的上述Python示例中重现双向进程通信?

3 个答案:

答案 0 :(得分:11)

在类UNIX系统上执行此操作的一种方法是打开一个管道,将管道重定向到stdoutstderr到fifo:

# Setup
system('mkfifo output.fifo')
p_out <- fifo('output.fifo', 'r')
p_in <- pipe('pdflatex &> output.fifo', 'w')

# See what TeX said on startup
readLines(p_out)
[1] "This is pdfTeX, Version 3.1415926-1.40.11 (TeX Live 2010)"

readLines(p_out)
character(0) # TeX has nothing more to say

# Tell TeX to do something
writeLines('\\documentclass{article}', p_in)
flush(p_in)

# See what it said in response
readLines(p_out)
[1] "**entering extended mode"                                                       
[2] "LaTeX2e <2009/09/24>"                                                           
[3] "Babel <v3.8l> and hyphenation patterns for english, dumylang, nohyphenation, ba"
[4] "sque, danish, dutch, finnish, french, german, ngerman, swissgerman, hungarian, "
[5] "italian, bokmal, nynorsk, polish, portuguese, spanish, swedish, loaded."        
[6] ""

不幸的是,Windows不支持fifo

答案 1 :(得分:4)

很久以前我也在Octave中使用了双向管道,所以,是的,这样做会很好。但仔细阅读help(pipe)并不表示这是支持。你会读到写,但似乎不是两者兼而有之。

但也许你可以作弊。打开一个管道写入一个应用程序,你可以调用stdout重定向到一个文件...然后继续读取该文件。但由于没有刷新缓冲区,可能会造成混乱。

答案 2 :(得分:1)

可以像这样在R中运行Jython中的那个部分。加载java(发生在第二个语句中)将很慢,但之后应该没问题。

library(rJython)

.Jython <- rJython()

jython.assign(.Jython, "x", "www.google.com")
jython.exec(.Jython, "from subprocess import *
p = Popen('nslookup', stdin=PIPE, stdout=PIPE)
p_stdin, p_stdout = p.communicate(x)")

cat(jython.get(.Jython, "p_stdin"), "\n\n")

最后一句话给出:

> cat(jython.get(.Jython, "p_stdin"), "\n\n")
Default Server:  UnKnown

Address:  192.168.0.1



> www.google.com