如何捕获系统的输出()

Yih*_*Xie 16 r stdout knitr

这个问题的动机是Rmarkdown没有将系统命令的结果输出到html文件.由于某种原因,system()R(或system2())中的输出无法被sink()或捕获capture.output(),因此目前knitr无法记录输出.例如,在R控制台中:

> system('ls')
DESCRIPTION
NAMESPACE
R
README.md
inst
man
Run Code Online (Sandbox Code Playgroud)

但在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,了解我为解决问题而提供的黑客攻击.

Jos*_*ich 5

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

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

您可以启动一个打印到的进程stdout,将其放在后台,然后启动R ...然后您将在"R输出"中看到该进程的输出,类似于system("ping -c5 8.8.8.8")从R 运行的情况.

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
> 
Run Code Online (Sandbox Code Playgroud)

  • 我不认为不可见的返回值是问题所在。我希望`capture.output()` 能够捕获stdout,尽管这不是文档中的内容(文档使用了一个模糊的“输出”一词,我不知道它是否暗示stdout)。例如,你可以`capture.output((function() {print("Hello world!"); invisible("hi")})())`,它从`print()`捕获`Hello world!` . 我的实际问题是为什么可以捕获“print()”的输出,而“system()”的输出却不能。要么`system()` 不写入标准输出,或者`capture.output()` 没有真正捕获标准输出。 (2认同)

CL.*_*CL. 5

您可以添加一个knitr::system屏蔽base::system. 用户可以像以前一样使用它system::base,但可以通过以下方式捕获输出capture.output

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

我承认,这有点老套,而且说实话,我不确定可能的副作用。但我认为这值得一试。