如何检查用于pipe()的命令是否失败?

时间:2019-06-06 12:00:27

标签: r io pipe signals

说,我编写了以下形式的压缩器函数:

compress <- function(text, file){
    c <- paste0("gzip -c > ",shQuote(file))
    p <- pipe(c, open = "wb")
    on.exit(close(p))
    writeLines(text, p)
}

现在我可以像这样压缩字符串了:

compress("Hello World", "test.gz")
system("zcat test.gz")
## Hello World

但是,如何检查gzip调用的程序pipe()是否成功?

例如

compress("Hello World", "nonexistent-dir/test.gz")
## sh: nonexistent-dir/test.gz: No such file or directory

导致在STDERR上打印错误消息,但是我无法创建R错误。该程序将继续而不保存我的文本。

我知道在这个例子中我可以检查目标文件是否存在。但是有许多可能的错误,例如磁盘空间不足,找不到程序,缺少某些库,找到了but the ELF interpreter was not等程序,我只是想不出任何方法来测试所有可能的错误。

我搜索了帮助页面?pipe,但找不到任何提示。

作为一种特定于UNIX的方法,我试图捕获SIGPIPE信号,但是找不到解决方法。到目前为止,[1] [2]

仍未回答有关此主题的堆栈溢出问题

如何检查用pipe()调用的程序的退出代码或过早终止?

1 个答案:

答案 0 :(得分:0)

我还没有找到使用pipe()的解决方案,但是包 processx 有解决方案。首先,我将外部进程创建为后台进程,获得与之的连接并写入该连接。

在我开始写之前,请检查该进程是否正在运行。编写完成后,我可以检查程序的退出代码。

library(processx)
p <- process$new("pigz","-c",stdin="|", stdout = "/tmp/test.gz")
if(!p$is_alive()) stop("Subprocess ended prematurely")
con <- p$get_input_connection()
# Write output
conn_write(con, "Hello World")
close(con)
p$wait()
if(p$get_exit_status() != 0) stop("Subprocess failed")
system("zcat /tmp/test.gz")