2015-03-07 15 views
5

Tôi đã viết một kịch bản R nhỏ để đọc JSON, trong đó hoạt động tốt nhưng khi đường ống vớiPiping Rscript cho lỗi sau khi sản lượng

Rscript myscript.R | head 

sự (đầy đủ, dự kiến) sản lượng trở lại với một lỗi

Error: ignoring SIGPIPE signal 
Execution halted 

Nhưng kỳ lạ tôi không thể loại bỏ điều này bằng đường ống thiết bị lỗi chuẩn để /dev/null sử dụng:

Rscript myscript.R | head 2>/dev/null 

Các lỗi tương tự là g iven ... có lẽ vì lỗi phát sinh trong lệnh Rscript? Đề xuất với tôi là đầu ra của lệnh head là tất cả STDOUT.

  • Piping STDOUT để /dev/null lợi nhuận chỉ được thông báo lỗi
  • Piping STDERR để /dev/null lợi nhuận chỉ được thông báo lỗi ...!

Việc đưa đầu ra cho mèo có vẻ là 'ẩn' - điều này không gây ra lỗi.

Rscript myscript.R | cat | head 

Có thể bỏ qua chuỗi ống sau lệnh cat nhưng có thể tôi bỏ qua điều gì đó quan trọng bằng cách không giải quyết lỗi.

Có cài đặt nào tôi cần sử dụng trong tập lệnh để cho phép đường ống mà không có lỗi không? Tôi muốn có kịch bản R tại sẵn sàng cho các nhiệm vụ nhỏ như được thực hiện với sự thích của Python và Perl, và nó sẽ nhận được khó chịu để luôn luôn phải thêm một vô dụng cat.

Có cuộc thảo luận về việc xử lý lỗi này trong C here, nhưng nó không ngay lập tức rõ ràng với tôi như thế nào điều này sẽ liên quan đến một kịch bản R.

Sửa Đáp lại câu trả lời @ lll, những kịch bản đầy đủ trong sử dụng (ở trên gọi là 'myscript.R') là

library(RJSONIO) 
note.list <- c('abcdefg.json','hijklmn.json') 
# unique IDs for markdown notes stored in JSON by Laverna, http://laverna.cc 
for (laverna.note in note.list) { 
    # note.file <- path.expand(file.path('~/Dropbox/Apps/Laverna/notes', 
    #         laverna.note)) 
    # For the purpose of this example run the script in the same 
    # directory as the JSON files 
    note.file <- path.expand(file.path(getwd(),laverna.note)) 
    file.conn <- file(note.file) 
    suppressWarnings(# warnings re: no terminating newline 
    cat(paste0(substr(readLines(file.conn), 2, 15)),'\n') # add said newline 
) 
    close(file.conn) 
} 

Rscript myscript.R đầu ra

"id":"abcdefg" 
"id":"hijklmn" 

Rscript myscript.R | head -1 đầu ra

"id":"abcdefg" 
Error: ignoring SIGPIPE signal 
Execution halted 

Đó là không rõ ràng với tôi điều gì sẽ chấm dứt 'sớm' ở đây

Chỉnh sửa 2 Có thể sao chép với readLines vì vậy tôi đã xóa chi tiết cụ thể về thư viện JSON trong ví dụ trên. Kịch bản và giả JSON gisted here.

Sửa 3 Có vẻ như nó có thể là có thể lấy đối số dòng lệnh bao gồm Ống và vượt qua chúng để pipe() - Tôi sẽ cố gắng này khi tôi có thể và giải quyết câu hỏi.

Trả lời

2

Lỗi này chỉ đơn giản là do cố gắng ghi vào đường ống mà không có quy trình được kết nối với đầu kia.Nói cách khác, kịch bản của bạn đã được nhấc lên và để lại khi đến đường ống và lệnh HEAD được gọi.

Lệnh tự có thể không là vấn đề; nó có thể là một cái gì đó trong kịch bản gây ra một kết thúc sớm hoặc điều kiện chủng tộc trước khi đến đường ống. Vì bạn đang nhận được sản lượng đầy đủ nó có thể không được nhiều của một mối quan tâm, tuy nhiên, mặt nạ các lỗi với các lệnh CLI như đã đề cập có lẽ không phải là cách tiếp cận tốt nhất.


Giải pháp dòng lệnh:

R không có một vài lệnh hữu ích để đối phó với trường hợp trong đó bạn có thể muốn người phiên dịch để chờ đợi, hay có lẽ ngăn chặn bất kỳ lỗi nào mà thông thường sẽ được xuất ra để stderr.

Đối với dòng lệnh R, thông báo lỗi được viết bằng ‘stderr’ sẽ được gửi đến thiết bị đầu cuối trừ khi ignore.stderr = TRUE. Họ có thể được chụp (trong vỏ rất có thể) bằng cách:

system("some command 2>&1", intern = TRUE) 

Ngoài ra còn có các wait lập luận nào có thể giúp giữ cho quá trình sống.

wait - lôgic (không phải NA) cho biết liệu trình thông dịch R có cần chờ lệnh hoàn thành hay chạy không đồng bộ. Điều này sẽ bị bỏ qua (và thông dịch viên sẽ luôn chờ) nếu intern = TRUE.

system("Rscript myscript.R | head 2>&1", intern = TRUE) 

Trên đây sẽ chờ đợi, và đầu ra sai sót, nếu có được ném.

system("Rscript myscript.R | head", intern = FALSE, ignore.stderr = TRUE) 

Ở trên sẽ không chờ đợi, nhưng sẽ chặn lỗi, nếu có.

+0

Cảm ơn, tôi đã cập nhật câu hỏi của mình. Tôi không thể nhìn thấy bất kỳ quá trình chấm dứt sớm mặc dù. Bạn có thể chỉnh sửa câu trả lời của mình để giải thích 'chấm dứt' (trừ khi nó đủ ngắn để nhận xét) không? Kịch bản là một vòng lặp for trên 2 phần tử, cả hai được xử lý trong đầu ra mà tôi thấy, vì vậy tôi không hiểu giai đoạn sớm nào có thể xảy ra. –

+0

Nó có thể là 'close (file.conn)' có lẽ nơi mọi thứ bị chấm dứt quá nhanh. Đôi khi loại hành vi này cũng được biết đến như là [điều kiện chủng tộc] (https://www.google.com/search?q=race+condition&ie=utf-8&oe=utf-8). Hãy thử bình luận ra 'close (file.conn)' một lúc rồi chạy lệnh và xem bạn có gặp phải vấn đề tương tự không. –

+0

Vấn đề là mặc dù tôi muốn một tập lệnh có thể bị xích vào các lệnh mới theo ý muốn. Tôi có thể lấy đường ống như một đối số bên trong 'system()' gọi là 'system (paste0 (" Rscript myscript.R | ", args), intern = TRUE)' ... nhưng ... để vượt qua một đường ống trong vì các đối số có vẻ sai? Nó sẽ chỉ làm việc cho một lệnh (sử dụng một '|' thực sự sẽ kết thúc đọc đối số) vì vậy làm thế nào một cuộc gọi hệ thống có thể chấp nhận và chuỗi đầu ra đường ống? –

Các vấn đề liên quan