【问题标题】:Capture output of system command within a function in R在 R 中的函数中捕获系统命令的输出
【发布时间】:2016-07-03 08:23:28
【问题描述】:

我正在使用包中的一个函数,该函数使用system2() 在函数中运行命令。这个特定的命令将一些东西打印到标准输出。我想捕获system2() 调用的输出,但是capture.output() 不起作用。我了解如何直接运行system2() 并捕获标准输出,但不了解如何在这种特定情况下获取它。

简单示例:

my_ls <- function() {
  system2("ls")
  return("Hello")
}
my_ls()
output <- capture.output(my_ls())
output

【问题讨论】:

  • 如有疑问?system2。您会看到使用参数stdout = T 将输出捕获为字符串。
  • my_ls 的返回值将始终只是“Hello”。尝试 capture.output 是没有意义的,要么使用 return() around the system2` 调用,要么在函数内颠倒这些命令的顺序。
  • @JeremyS 是的,我已经知道了。我的问题的重点是 system2 调用在包中的函数内,我无法编辑该函数来设置 stdout = T,所以我正在寻找解决方法。
  • 您可以通过某种方式编辑函数。如果函数是MyFoo,则输入MyFoo,注意没有括号,你会得到函数的R代码,复制它并进行更改并保存为新函数MyFoo2例如
  • help(stdin) 谈论“控制台”和“C 级标准输入”-capture.output 获得“控制台”输出,system2 输出到“C 级标准输出” ' 我想。

标签: r system


【解决方案1】:

这是一个解决方案...但请注意,它适用于我的 Linux,可能适用于 Mac,我怀疑它适用于 Windows...

创建两个Rcpp 函数:

library(Rcpp)
cppFunction('void redir(){FILE* F=freopen("/tmp/capture.txt","w+",stdout);}')
cppFunction('void resetredir(){FILE* F=freopen("/dev/tty","w+",stdout);}')

第一个会将所有内容发送到该文件。第二个将重置它。问题是,在第一次交互之后,您将看不到任何东西。所以要小心...

所以最初system2 发送到控制台:

> system2("echo", "hello")
hello

但是在redir/resetredir 中封装一个调用会将其发送到文件中:

> redir(); system2("echo","hello world this time") ; resetredir()
> # prompt returns!

现在我们有了:

$ cat /tmp/capture.txt 
hello world this time

如果这是其他包的输出,您必须使用 R 的文件 I/O 例程将其读入。

狡猾的一点是在重置代码中使用/dev/tty - 我不确定它是否适用于 Mac 或 Windows。如果您不关心重置标准输出然后跳过它,并确保您知道如何在不看到您键入的内容的情况下完全 R。我也不确定这是否适用于可能具有不同控制台概念的 RStudio....

【讨论】:

  • 非常酷,谢谢。你说得对,resetredir() 似乎不适用于 Mac/RStudio,但这对我来说并不重要。
  • 函数 redir() 在 Windows 上运行良好。但是,resetredir() 应定义为 cppFunction('void resetredir(){FILE* F=freopen("CON","w+",stdout);}')
猜你喜欢
  • 1970-01-01
  • 2014-01-27
  • 1970-01-01
  • 2014-12-26
  • 2010-12-25
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 2019-01-05
相关资源
最近更新 更多