如何捕获系统的输出()

时间:2016-04-29 01:58:28

标签: r stdout knitr

这个问题是由Rmarkdown not outputting results of system command to html file推动的。出于某种原因,system()system2()无法捕获R(或sink())中capture.output()的输出,因此目前无法 knitr < / strong>记录输出。例如,在R控制台中:

> system('ls')
DESCRIPTION
NAMESPACE
R
README.md
inst
man

但在 knitr 文档中,您将看不到输出,因为capture.output(system('ls'))character(0),即无法捕获输出。当然,正如我在回答这个问题时提到的那样,我可以做cat(system('ls', intern = TRUE), sep = '\n'),但这有点尴尬。我想知道这是否是一种在不使用system()intern = TRUE的情况下捕获cat()输出的方法。

更新:请参阅https://github.com/yihui/knitr/issues/1203了解我为解决问题而提供的黑客攻击。

2 个答案:

答案 0 :(得分:5)

我认为你不能这样做(至少在* nix系统上;我没有方便的Windows / Mac系统)因为system似乎无形地返回执行的命令返回的值,并且R似乎没有将命令的输出重定向到R控制台。

这是因为终端的stdout与R控制台“stdout”不同。您在R会话中看到的是终端的stdout和R进程输出的混合。 capture.output正在寻找R流程的输出,而不是从父流程到stdout的所有输出。

你可以开始一个打印到stdout的过程,把它放在后台,然后启动R ......然后你会在你的“R输出”中看到这个过程的输出,就像你有从R。

运行system("ping -c5 8.8.8.8")
josh@computer: /home/josh
> ping -c5 8.8.8.8 & R
[1] 5808
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=46 time=39.9 ms

R version 3.2.4 Revised (2016-03-16 r70336) -- "Very Secure Dishes"
Copyright (C) 2016 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu (64-bit)

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

  Natural language support but running in an English locale

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> 64 bytes from 8.8.8.8: icmp_seq=2 ttl=46 time=38.1 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=46 time=38.3 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=46 time=38.4 ms
64 bytes from 8.8.8.8: icmp_seq=5 ttl=46 time=38.3 ms

--- 8.8.8.8 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4003ms
rtt min/avg/max/mdev = 38.176/38.656/39.986/0.703 ms

> q()
Save workspace image? [y/n/c]: n
[1]+  Done                    ping -c5 8.8.8.8

josh@computer: /home/josh
> 

答案 1 :(得分:4)

您可以添加屏蔽knitr::system的函数base::system。用户可以像system::base一样使用它,但capture.output可以捕获输出:

system <- function(...) {
  stopifnot(!any(names(list(...)) %in% "intern"))
  result <- base::system(..., intern = TRUE)
  print(result)
}

我承认,这有些愚蠢,说实话,我不确定可能的副作用。但我认为值得一试。