管道Rscript输出后出错

时间:2015-03-07 14:19:03

标签: r unix pipe

我写了一个小的R脚本来读取JSON,它可以很好地工作但是用

滚动
Rscript myscript.R | head

(完整的,预期的)输出返回错误

Error: ignoring SIGPIPE signal
Execution halted

奇怪的是我无法通过使用以下方式将STDERR传送到/dev/null来删除它:

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

给出了同样的错误...大概是因为Rscript命令中出现了错误?对我的建议是head命令的输出都是STDOUT。

  • 将STDOUT路由到/dev/null仅返回错误消息
  • 将STDERR路由到/dev/null仅返回错误消息...!

将输出管道输送到猫似乎是不可见的' - 这不会导致错误。

Rscript myscript.R | cat | head

在cat命令之后可以进一步进行管道连接,但感觉我可能会因为没有解决错误而忽略了一些重要的事情。

我是否需要在脚本中使用设置以允许管道没有错误?我希望R脚本可以像Python和Perl那样为小任务做好准备,并且总是不得不添加无用的cat

有人讨论过在C here中处理此错误,但我并不清楚这与R脚本有何关联。

修改为了回应@ lll的回答,正在使用的完整脚本(上面称为' myscript.R')是

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输出

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

Rscript myscript.R | head -1输出

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

我不清楚什么会终止&#39;早期&#39;这里

编辑2 可以使用readLines进行复制,因此我在上面的示例中删除了特定于JSON库的详细信息。脚本和虚拟JSON gisted here

编辑3 似乎可以采用命令行参数包括管道并将它们传递给pipe() - 我试试这个我什么时候可以解决这个问题。

1 个答案:

答案 0 :(得分:4)

错误只是由于尝试写入管道而没有连接到另一端的进程。换句话说,在到达管道并且调用HEAD命令时,您的脚本已经拾取并离开。

命令本身可能不是的问题;它可能是脚本中的某些东西导致在到达管道之前提前终止或竞争状态。由于您获得完整输出,因此可能不会引起太大关注,但是,如上所述,使用其他CLI命令屏蔽错误可能并不是最佳方法。


命令行解决方案:

R确实有一些有用的命令可用于处理您可能希望解释器等待的实例,或者可能抑制通常会输出到stderr的任何错误。

  

对于命令行R,将发送写入'stderr'的错误消息   终端除非ignore.stderr = TRUE。他们可以被捕获(在   最有可能的贝壳):

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

还有wait参数可以帮助保持进程的活跃。

  

wait - 逻辑(不是NA)表示R解释器是否应该   等待命令完成,或异步运行它。这将会   忽略(并且解释器将始终等待)   如果intern = TRUE

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

上面会等待,并输出错误,如果有的话。

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

以上不会等待,但会抑制错误,如果有的话。