Чтение-запись канала () связи в R - PullRequest
11 голосов
/ 18 марта 2011

Большинство языков поддерживают двустороннее общение процессов. Например, в 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!) Воспроизвести двустороннее взаимодействие процессов в приведенном выше примере Python на R?

Ответы [ 3 ]

11 голосов
/ 06 апреля 2011

Один из способов сделать это в 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.

4 голосов
/ 18 марта 2011

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

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

1 голос
/ 19 марта 2011

Можно запустить эту часть в 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 
...