如何捕获 system() 的输出
How to capture the output of system()
这个问题是由 Rmarkdown not outputting results of system command to html file 提出的。由于某些原因,system()
在R(或system2()
)中的输出无法被sink()
或capture.output()
捕获,所以目前没有办法knitr 记录输出。比如在R控制台中:
> system('ls')
DESCRIPTION
NAMESPACE
R
README.md
inst
man
但在 knitr 文档中,您将看不到输出,因为 capture.output(system('ls'))
是 character(0)
,即无法捕获输出。当然,我可以像我在那个问题的答案中提到的那样 cat(system('ls', intern = TRUE), sep = '\n')
,但这有点尴尬。我想知道这是否是一种在不使用 intern = TRUE
和 cat()
的情况下捕获 system()
输出的方法。
更新:请参阅 https://github.com/yihui/knitr/issues/1203 以了解我提供的解决问题的 hack。
我不认为你可以这样做(至少在 *nix 系统上;我手边没有 Windows/Mac 系统)因为 system
似乎无形地 return由执行的命令编辑的值 return,并且 R 似乎没有将命令的输出重定向到 R 控制台。
这是因为您的终端 stdout
与 R 控制台 "stdout" 不同。您在 R 会话中看到的是终端 stdout
和 R 进程输出的混合。 capture.output
正在寻找 R 进程的输出,而不是从父进程到 stdout
的所有输出。
您可以启动一个打印到 stdout
的进程,将其置于后台,然后启动 R... 您将在 "R output" 中看到该进程的输出,类似于如果你有 运行 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
>
您可以添加一个函数 knitr::system
来屏蔽 base::system
。用户可以像 system::base
一样使用它,但输出可以通过 capture.output
:
捕获
system <- function(...) {
stopifnot(!any(names(list(...)) %in% "intern"))
result <- base::system(..., intern = TRUE)
print(result)
}
我承认,这有点老套,老实说,我不确定可能的副作用。但我认为这值得一试。
这个问题是由 Rmarkdown not outputting results of system command to html file 提出的。由于某些原因,system()
在R(或system2()
)中的输出无法被sink()
或capture.output()
捕获,所以目前没有办法knitr 记录输出。比如在R控制台中:
> system('ls')
DESCRIPTION
NAMESPACE
R
README.md
inst
man
但在 knitr 文档中,您将看不到输出,因为 capture.output(system('ls'))
是 character(0)
,即无法捕获输出。当然,我可以像我在那个问题的答案中提到的那样 cat(system('ls', intern = TRUE), sep = '\n')
,但这有点尴尬。我想知道这是否是一种在不使用 intern = TRUE
和 cat()
的情况下捕获 system()
输出的方法。
更新:请参阅 https://github.com/yihui/knitr/issues/1203 以了解我提供的解决问题的 hack。
我不认为你可以这样做(至少在 *nix 系统上;我手边没有 Windows/Mac 系统)因为 system
似乎无形地 return由执行的命令编辑的值 return,并且 R 似乎没有将命令的输出重定向到 R 控制台。
这是因为您的终端 stdout
与 R 控制台 "stdout" 不同。您在 R 会话中看到的是终端 stdout
和 R 进程输出的混合。 capture.output
正在寻找 R 进程的输出,而不是从父进程到 stdout
的所有输出。
您可以启动一个打印到 stdout
的进程,将其置于后台,然后启动 R... 您将在 "R output" 中看到该进程的输出,类似于如果你有 运行 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
>
您可以添加一个函数 knitr::system
来屏蔽 base::system
。用户可以像 system::base
一样使用它,但输出可以通过 capture.output
:
system <- function(...) {
stopifnot(!any(names(list(...)) %in% "intern"))
result <- base::system(..., intern = TRUE)
print(result)
}
我承认,这有点老套,老实说,我不确定可能的副作用。但我认为这值得一试。