我一直在玩system()
和system2()
以获得乐趣,让我感到震惊的是我可以在对象中保存输出或退出状态。玩具示例:
X <- system("ping google.com",intern=TRUE)
给我输出,而
X <- system2("ping", "google.com")
给我退出状态(在这种情况下为1,谷歌不接受ping)。如果我想要输出和退出状态,我必须进行2次系统调用,这看起来有点矫枉过正。如何才能同时使用一个系统调用?
编辑:我希望在控制台中同时使用这两者,如果可能的话,在stdout="somefile.ext"
调用中使用system2
并在随后读取它时不会覆盖临时文件。
答案 0 :(得分:12)
我对你对system2的描述感到有点困惑,因为它有stdout和stderr参数。因此它能够返回退出状态,stdout和stderr。
> out <- tryCatch(ex <- system2("ls","xx", stdout=TRUE, stderr=TRUE), warning=function(w){w})
> out
<simpleWarning: running command ''ls' xx 2>&1' had status 2>
> ex
[1] "ls: cannot access xx: No such file or directory"
> out <- tryCatch(ex <- system2("ls","-l", stdout=TRUE, stderr=TRUE), warning=function(w){w})
> out
[listing snipped]
> ex
[listing snipped]
答案 1 :(得分:11)
从R 2.15起,当system2
和/或stdout
为TRUE时,stderr
会将返回值作为属性。这样可以轻松获取文本输出和返回值。
在此示例中,ret
最终成为具有属性"status"
的字符串:
> ret <- system2("ls","xx", stdout=TRUE, stderr=TRUE)
Warning message:
running command ''ls' xx 2>&1' had status 1
> ret
[1] "ls: xx: No such file or directory"
attr(,"status")
[1] 1
> attr(ret, "status")
[1] 1
答案 2 :(得分:5)
我建议在这里使用此功能:
robust.system <- function (cmd) {
stderrFile = tempfile(pattern="R_robust.system_stderr", fileext=as.character(Sys.getpid()))
stdoutFile = tempfile(pattern="R_robust.system_stdout", fileext=as.character(Sys.getpid()))
retval = list()
retval$exitStatus = system(paste0(cmd, " 2> ", shQuote(stderrFile), " > ", shQuote(stdoutFile)))
retval$stdout = readLines(stdoutFile)
retval$stderr = readLines(stderrFile)
unlink(c(stdoutFile, stderrFile))
return(retval)
}
这只适用于接受&gt;的类似Unix的shell。和2>符号,cmd参数不应重定向输出本身。但它确实可以解决问题:
> robust.system("ls -la")
$exitStatus
[1] 0
$stdout
[1] "total 160"
[2] "drwxr-xr-x 14 asieira staff 476 10 Jun 18:18 ."
[3] "drwxr-xr-x 12 asieira staff 408 9 Jun 20:13 .."
[4] "-rw-r--r-- 1 asieira staff 6736 5 Jun 19:32 .Rapp.history"
[5] "-rw-r--r-- 1 asieira staff 19109 11 Jun 20:44 .Rhistory"
$stderr
character(0)