Read-write pipe() communication in R
Most languages support two-way process communication. For example, in Python, I can (sloppily) do:
>>> from subprocess import *
>>> p = Popen('nslookup', stdin=PIPE, stdout=PIPE)
>>> p_stdin, p_stdout = p.communicate("www.google.com")
>>> print p_stdin
Server: ...
In R, I can only seem to go one way, regardless of whether I open my pipe with "r+" or "w+". Furthermore, even if I run a script via R -f ...
or R < ...
, weird behavior ensues in the actual console stdin/stdout.
My question boils down to the follo开发者_如何学JAVAwing - is it possible (without writing a C method!) to reproduce the two-way process communication in the above Python example in R?
One way to do it on UNIX-like systems would be to open a pipe to a process that is redirecting stdout
and stderr
to a 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] ""
Unfortunately, fifo
isn't supported on Windows.
A long time ago I also used two-way pipes in Octave so, yes, this would be nice to have. But a perusal of help(pipe)
does not suggest that this is support. You get read or write, but seemingly not both.
But maybe you can cheat. Open a pipe to write into an app which you can call with a stdout redirection to a file ... and then keep reading that file. Could be a mess due to non-flushed buffers though.
Its possible to run that part in Jython from R like this. Loading java (which occurs in the second statement) will be slow but after that it should be ok.
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")
The last statement gives:
> cat(jython.get(.Jython, "p_stdin"), "\n\n")
Default Server: UnKnown
Address: 192.168.0.1
> www.google.com
精彩评论