2011-08-10 44 views
16

Tôi đã chơi một chút với system()system2() để giải trí, và nó khiến tôi có thể lưu đầu ra hoặc trạng thái thoát trong một đối tượng. Một ví dụ đồ chơi:Chụp cả trạng thái thoát và đầu ra từ một cuộc gọi hệ thống trong R

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

mang lại cho tôi đầu ra, trong khi

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

mang lại cho tôi những trạng thái thoát (1 trong trường hợp này, google không mất ping). Nếu tôi muốn cả đầu ra và trạng thái thoát, tôi phải thực hiện 2 cuộc gọi hệ thống, điều này có vẻ hơi quá mức. Làm thế nào tôi có thể nhận được cả hai chỉ sử dụng một cuộc gọi hệ thống?

EDIT:. Tôi muốn có cả hai trong giao diện điều khiển, nếu có thể mà không đi qua một tập tin tạm thời bằng cách sử dụng stdout="somefile.ext" trong system2 cuộc gọi và sau đó đọc nó trong

+0

Bạn đang sử dụng Linux hoặc Windows? Tôi thậm chí không thể có được stdout = "somefile.ext" để làm việc trên Windows, nhưng nó hoạt động tốt trên Linux ... – Tommy

+0

Tôi khuyên bạn nên thêm 'linux' vào thẻ của bạn, cùng với bất kỳ shell bạn đang sử dụng. Điều này có thể mời một số giải pháp từ các chuyên gia hệ điều hành. – Iterator

+0

Xin lỗi cho OP và @Gavin, tôi có thể nhầm lẫn: Tôi nghĩ đây rõ ràng hoặc ngầm là Linux, nhưng tôi thấy OP thậm chí không đề cập đến Linux và nó có thể là một hệ điều hành khác cho tất cả những gì tôi biết. – Iterator

Trả lời

10

Tính R 2.15, system2 sẽ cung cấp cho các giá trị trả về là một thuộc tính khi stdout và/hoặc stderr là TRUE. Điều này làm cho nó dễ dàng để có được đầu ra văn bản và giá trị trả lại.

Trong ví dụ này, ret kết thúc lên được một chuỗi với một thuộc tính "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

Tôi là một chút bối rối bởi mô tả của bạn của system2, bởi vì nó có đối số stdout và stderr. Vì vậy, nó có thể trả về cả trạng thái thoát, stdout và 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 Rất tốt. Nhân tiện, chào mừng bạn đến với SO, nơi mà không phải ai cũng đọc thông tin trợ giúp cho các lệnh R. ;-) – Iterator

+0

+1 Ditto ....... – Andrie

+0

+1, vì nó đang sử dụng các cảnh báo nội bộ và các thủ thuật lỗi của R. Tôi có thể cắt bỏ trạng thái thoát khỏi thông báo cảnh báo. Tôi biết tôi có thể sử dụng stdout = TRUE, nhưng trạng thái thoát là mối quan tâm chính của tôi. Đó là lý do tại sao tôi không làm điều đó. –

4

tôi đề nghị sử dụng chức năng này ở đây:

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

này sẽ chỉ làm việc trên một vỏ Unix-like chấp nhận ký hiệu> và 2>, và đối số cmd không nên tự chuyển hướng đầu ra. Nhưng nó thực hiện thủ thuật:

> 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) 
Các vấn đề liên quan