In R, we can open a pipe connection using pipe()
and write to it. I observed the following situation that I do not quite understand. Let's use a python
pipe for example:
在R中,我们可以使用pipe()打开管道连接并写入它。我观察到以下我不太了解的情况。我们使用python管道例如:
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)
What I was expecting was the output from print()
would be immediately shown in the R console, but the fact is the output comes only after I close the pipe connection:
我期待的是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)
1
3
3
So my question is, how can I get the output before I close the connection? Note that it does not seem to be possible to capture the output using capture.output()
, either:
所以我的问题是,在关闭连接之前如何获得输出?请注意,似乎无法使用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)
The background of this question is the knitr
engines. For the interpreted languages like Python, I wish I can open a persistent "terminal" so that I can keep on writing code into it and get output from it. I'm not sure if pipe()
is the correct way to go, though.
这个问题的背景是针织引擎。对于像Python这样的解释语言,我希望我可以打开一个持久的“终端”,这样我就可以继续编写代码并从中获取输出。不过,我不确定pipe()是否是正确的方法。
1 个解决方案
#1
5
Python notices that the input is not interactive and waits until the connection is closed to parse and execute the code. You can use the -i
option to force it to stay in interactive mode. (but the output is a bit mangled).
Python注意到输入不是交互式的,并且等待连接关闭以解析和执行代码。您可以使用-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)
Your actual problem is more complicated: you need to both read and write to the same connection. I do not know how to do that in a portable way, but you can use a pipe and a named pipe (a "fifo") on platforms that support them.
您的实际问题更复杂:您需要同时读取和写入同一连接。我不知道如何以便携方式执行此操作,但您可以在支持它们的平台上使用管道和命名管道(“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"
#1
5
Python notices that the input is not interactive and waits until the connection is closed to parse and execute the code. You can use the -i
option to force it to stay in interactive mode. (but the output is a bit mangled).
Python注意到输入不是交互式的,并且等待连接关闭以解析和执行代码。您可以使用-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)
Your actual problem is more complicated: you need to both read and write to the same connection. I do not know how to do that in a portable way, but you can use a pipe and a named pipe (a "fifo") on platforms that support them.
您的实际问题更复杂:您需要同时读取和写入同一连接。我不知道如何以便携方式执行此操作,但您可以在支持它们的平台上使用管道和命名管道(“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"