寻找一个选项,让我可以将R诊断消息(由message()
生成)重定向到stdout
,而不是默认情况下stderr
。
message
手册说明:
默认处理程序将消息发送到stderr()连接。
所以问题是如何更改此默认行为?仍然保留warning()
和stop()
的重定向。
已尝试接收type='message'
但它会重定向所有(消息,警告,错误)。
如果有人愿意测试,这是示例脚本exec_test.R
:
print("using print")
cat("using cat\n")
message("using message")
warning("using warning")
stop("using stop")
q("no")
然后将执行:
Rscript exec_test.R 1>> exec_test.Rout 2>> exec_test_error.Rout
我不知道如何使用2>&1
,因为我的脚本产生了大量的message
,很少出现真正的错误,因此我需要将这些日志存储在单独的文件中。
答案 0 :(得分:2)
虽然这很可能不是最佳做法,但您可以使用默认情况下写入message
的版本覆盖stdout()
,对吗?
message <- function (..., domain = NULL, appendLF = TRUE)
{
args <- list(...)
cond <- if (length(args) == 1L && inherits(args[[1L]], "condition")) {
if (nargs() > 1L)
warning("additional arguments ignored in message()")
args[[1L]]
}
else {
msg <- .makeMessage(..., domain = domain, appendLF = appendLF)
call <- sys.call()
simpleMessage(msg, call)
}
defaultHandler <- function(c) {
cat(conditionMessage(c), file = stdout(), sep = "")
}
withRestarts({
signalCondition(cond)
defaultHandler(cond)
}, muffleMessage = function() NULL)
invisible()
}
答案 1 :(得分:2)
OP通过Rscript命令显示执行并使用一些I / O重定向。如果你想使用重定向记录所有内容并且只在出错时显示给控制台,我发现最好的方法是使用||
检查脚本在打印到屏幕之前是否具有非零退出状态:
Rscript myrscript.R > temp.log 2>&1 || cat temp.log
这个方法严格依赖于打印的退出代码,它只部分地绕过message()
进入stderr,但我认为这个例子很有用,因为消息不一定会触发非零退出状态,你可以用这种方法继续安静地登录。
如果您想更进一步并继续添加到单个日志文件中,那么这将有效:
Rscript myrscript.R > temp.log 2>&1 || cat temp.log && cat temp.log >> persistent.log && rm temp.log
此命令的伪代码为:
stderr
和stdout
重定向到temp.log 答案 2 :(得分:1)
使用sink
。这是对您的代码的修改:
sink(stdout(), type = "message") # sink messages to stdout
print("using print")
cat("using cat\n")
message("using message")
warning("using warning")
sink(NULL, type="message") # close the sink
warning("after ending sink") # this will be the only thing in your err file
q("no")
答案 3 :(得分:0)
将@Thomas和@ branch14的答案结合在一起,这就是我想出的:
.stderr_message <- message
message <- function(...) {
sink(stdout(), type = "message")
.stderr_message(...)
sink(NULL, type = "message")
}
我使用此代码在外壳上对此进行了验证
.stderr_message <- message
message <- function(...) {
sink(stdout(), type = "message")
.stderr_message(...)
sink(NULL, type = "message")
}
print(1)
message(1)
没有我的message()
:
> Rscript bug.R 2> >(sed 's/^/stderr: /') > >(sed 's/^/stdout: /')
stdout: [1] 1
stderr: 1
> Rscript bug.R 2> >(sed 's/^/stderr: /') > >(sed 's/^/stdout: /')
stdout: [1] 1
stdout: 1