2013-07-20 11 views
5

Rでは、pipe()を使用してパイプ接続を開いて書き込むことができます。私は次のような状況をよく理解していませんでした。のは、例えばpythonパイプを使用してみましょう:Rでパイプ接続を閉じる前にパイプ接続から出力を得るには?

print()からの出力は、直ちにRコンソールに表示されましたが、実際には、出力は私がパイプ接続を閉じた後にのみ付属している私は何を期待していた

z = pipe('python', open='w+') 

cat('x=1\n', file=z) 
cat('print(x)\n', file=z) 
cat('print(x+2)\n', file=z) 
cat('print(x+2\n', file=z) 
cat(')\n', file=z) 

close(z) 

> z = pipe('python', open='w+') 
> 
> cat('x=1\n', file=z) 
> cat('print(x)\n', file=z) 
> cat('print(x+2)\n', file=z) 
> cat('print(x+2\n', file=z) 
> cat(')\n', file=z) 
> 
> close(z) 
1 
3 
3 

私の質問は、どうすれば接続を閉じる前に出力を得ることができるのですか?どちらか、それはcapture.output()を使用して出力をキャプチャすることは可能であると思わないことに注意してください:

> z = pipe('python', open='w+') 
> 
> cat('x=1\n', file=z) 
> cat('print(x)\n', file=z) 
> cat('print(x+2)\n', file=z) 
> cat('print(x+2\n', file=z) 
> cat(')\n', file=z) 
> 
> x = capture.output(close(z)) 
1 
3 
3 
> x 
character(0) 

この質問の背景がknitr enginesです。 Pythonのようなインタプリタ言語では、永続的な "ターミナル"を開いてコードを書いて、そこから出力を得ることができればいいと思います。私はpipe()が正しい方法であるかどうか分からない。

答えて

5

入力は対話的ではないことに気付き、コードを解析して実行するために接続が閉じられるまで待機します。 -iオプションを使用すると、強制的に対話モードを維持できます。 (しかし、出力は少し混乱しています)。

z = pipe('python -i', open='w') 
cat('x=1\n', file=z) 
cat('print(x)\n', file=z) 
cat('print(x+2)\n', file=z) 
cat('print(x+2\n', file=z) 
cat(')\n', file=z) 
Sys.sleep(2) 
# Python 2.7.4 (default, Apr 19 2013, 18:28:01) 
# [GCC 4.7.3] on linux2 
# Type "help", "copyright", "credits" or "license" for more information. 
# >>> >>> 1 
# >>> 3 
# >>> ... 3 
# >>> 
close(z) 

実際の問題はより複雑です。同じ接続に読み書きする必要があります。 私はそれをポータブルな方法で行う方法はわかりませんが、パイプとそれをサポートするプラットフォーム上で名前付きパイプ( "fifo")を使うことができます。

stopifnot(capabilities("fifo")) 
system('mkfifo /tmp/Rpython.fifo') 
output <- fifo('/tmp/Rpython.fifo', 'r') 
input <- pipe('python -i > /tmp/Rpython.fifo', 'w') 
python_code <- " 
x=1 
print(x) 
print(x+2) 
print(x+2 
) 
" 
cat(python_code, file = input) 
flush(input) 
Sys.sleep(2) # Wait for the results 
result <- readLines(output) 
result 
# [1] "1" "3" "3" 
関連する問題