2011-08-10 70 views
16

爲了好玩,我一直在玩system()system2(),它讓我感到很震驚,我可以保存對象中的輸出或退出狀態。玩具例子:在R中捕獲退出狀態和系統調用輸出

X <- system("ping google.com",intern=TRUE) 

給我的輸出,而

X <- system2("ping", "google.com") 

給我的退出狀態(在這種情況下1,谷歌不採取平)。如果我想要輸出和退出狀態,我必須做2個系統調用,這似乎有點矯枉過正。我怎樣才能同時使用一個系統調用?

編輯:我想如果可能的話,有兩個控制檯,而不受system2呼叫使用stdout="somefile.ext",隨後閱讀它會在臨時文件

+0

您使用的是Linux還是Windows?我甚至無法使用stdout =「somefile.ext」在Windows上工作,但它在Linux上正常工作... – Tommy

+0

我建議在您的標籤中加入'linux',以及您正在使用的任何外殼。這可以邀請操作系統專家提供一些解決方案。 – Iterator

+0

對OP和@Gavin的道歉,我可能會誤解:我認爲這是Linux的明示或暗示,但我看到OP甚至沒有提到Linux,它可能是我知道的另一個操作系統。 – Iterator

回答

10

作爲R 2.15,system2會給返回值作爲屬性時stdout和/或stderr是TRUE。這可以很容易地獲得文本輸出和返回值。

在這個例子中,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 
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] 
+5

+1非常好。順便說一句,歡迎來到SO,那裏不是每個人都閱讀R命令的幫助信息。 ;-) – Iterator

+0

+1同上....... – Andrie

+0

+1,因爲它使用R的內部警告和錯誤技巧。我可以從警告消息中刪除退出狀態。我知道我可以使用stdout = TRUE,但退出狀態是我最關心的問題。這就是爲什麼我沒有那樣做。 –

4

我建議使用此功能在這裏:

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) 
} 

這將僅在類Unix外殼工作接受>和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)