Считывание-запись канала() связи в R

Большинство языков поддерживают двустороннюю связь процесса. Например, в Python я могу (sloppily) делать:

>>> 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 +". Более того, даже если я запускаю script через R -f ... или R < ..., в реальной консоли stdin/stdout возникает странное поведение.

Мой вопрос сводится к следующему: возможно ли (без написания метода C!) воспроизвести двустороннюю связь процесса в приведенном выше примере Python в R?

Ответ 1

Давным-давно я также использовал двухсторонние каналы в Octave, поэтому да, это было бы неплохо иметь. Но прочтение help(pipe) не предполагает, что это поддержка. Вы читаете или пишите, но, похоже, не оба.

Но, может быть, вы можете обмануть. Откройте трубу для записи в приложение, которое вы можете вызвать с перенаправлением stdout в файл... и затем продолжайте читать этот файл. Однако это может быть беспорядок из-за не очищенных буферов.

Ответ 2

Один из способов сделать это в UNIX-подобных системах - это открыть канал для процесса, который перенаправляет stdout и stderr на 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] ""

К сожалению, fifo не поддерживается в Windows.

Ответ 3

Его можно запустить эту часть в Jython из R, как это. Загрузка 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