【问题标题】:How do I silence this specific message written to terminal/file (when calling an 'Rscript' via a bash script)如何使写入终端/文件的特定消息静音(通过 bash 脚本调用“Rscript”时)
【发布时间】:2019-03-27 17:13:51
【问题描述】:

我正在编写一个 bash 脚本(在 Linux 系统上从终端调用),该脚本在使用一些简单的用户输入启动“rscript”之前创建一个日志文件。但是,我在控制日志文件中包含哪些消息(或发送到终端)时遇到了问题,并且找不到任何解决方案来排除一个特定的 R 包加载消息:

已加载 WGCNA 1.66 包。

换句话说,我需要一种方法来(仅)使该特定消息静音,该消息在成功加载 WGCNA 包时打印。

我会尽量保持代码的非特定性,希望它更容易理解。

下面的块是一个骨架(不包括一些不相关的代码),后面会跟着我尝试过的一些不同的变体。在哪里,最初我尝试使用 sink()suppressPackageStartupMessages() 控制 R 脚本的输出,我认为这应该足够了。

bash 脚本

#!/usr/bin/env bash

read RDS
DATE=`date +%F-%R`
LOG=~/path/log/$DATE.log
touch $LOG
export ALLOW_WGCNA_THREADS=4
Rscript ~/path/analysis.R $RDS $DATE $LOG

R 脚本

#!/usr/bin R

# object set-up
rds.path <- "~/path/data/"
temp.path <- "~/path/temp/"
pp.data <- readRDS(paste0(rds.path, commandArgs(T)[1]))
file.date <- paste0(commandArgs(T)[2], "_")

# set up error logging
log.file <- file(commandArgs(T)[3], open="a")
sink(log.file, append=TRUE, type="message")
sink(log.file, append=TRUE, type="output")

# main pkg call
if(suppressPackageStartupMessages(!require(thePKG))){
  stop("\nPlease follow the below link to install the requested package (thePKG) with relevant dependencies\n https://link.address")
}

# thePKG method call
cat("> Running "method"\n", append=TRUE)
module <- method(thePKG_input = pp.data, ppi_network = ppi_network)

# reset sink and close file connection
sink(type="message")
sink(type="output")
close(log.file)

这不会向终端输出任何内容(这很好),包括日志文件中的以下内容:

已加载 WGCNA 1.66 包。

> 运行“方法”

错误:添加错误以验证它是否正确打印到文件中


我想保持我的日志文件尽可能干净和准确(并避免终端混乱),因此希望删除包加载消息。我已经尝试了以下...

i. 从 R 脚本中省略 sink() 调用,并添加

&>> $LOG

到 bash 'Rscript' 调用。导致与上面相同的文件输出。

ii.i 相同,但将 suppressPackageStartupMessages() 替换为 suppressMessages(),结果是与上面相同的文件输出。

iii.i相同,但添加了

... require(thePKG, quietly=TRUE)

在 R 脚本中# main pkg call,结果相同。

这些是我遇到的潜在解决方案,并尝试了不同的变体,但没有积极的结果。


我还想知道 WGCNA 包是否在 PKG 的 !require 循环“外部”加载,因为它不受该调用的 suppressMessages() 影响。但是,在 if-require(thePKG) 调用之前引入一个故意的错误(终止了进程)删除了消息——暗示它在循环内启动。 我还尝试在 R 脚本的开头单独调用 WGCNA,并在其中添加了 suppressMessages(),但这也不起作用。 bash 脚本中使用的导出函数不会影响结果(据我所知),删除它会扩展加载消息以包含以下内容(截断以节省空间):

已加载 WGCNA 1.66 包。

重要提示:您的系统似乎支持多线程,但在 R 的 WGCNA 中未启用。

要在 WGCNA 中允许所有可用内核的多线程,请在 R 中使用 allowWGCNAThreads()。如有必要,请使用 disableWGCNAThreads() 禁用线程。

(...)


我知道我可以(仅)将输出发送到 /dev/null,但我仍然想要其他输出打印到文件(例如 > 运行“方法”)。

有人对如何删除此消息有建议吗?我是 R 编程的新手,刚开始使用 Linux (Ubuntu LTS),所以在回答时请记住这一点。

提前致谢。

【问题讨论】:

    标签: r bash file-io error-logging


    【解决方案1】:

    我可以从您的问题中收集以下执行流程:

    Bash_Script ----> R_Script ----> Output_to_terminal (and also a log file probably)

    对于所述要求,以下命令(在 bash 中)可以帮助您:

    • grep - 此命令可帮助您搜索模式

    • 管道 (|) - 这是 Linux 中的运算符,可帮助您将一个命令的输出作为输入重定向到另一个命令以进行进一步处理(例如,A | B

    • tee - 此命令接受任何输入并将其转发到文件 + 标准输出(终端)

    因此,您可以在 bash 文件中混合和匹配上述命令以获得所需的输出:

    你可以扩展

    Rscript ~/path/analysis.R $RDS $DATE $LOG
    

    Rscript ~/path/analysis.R "$RDS" "$DATE" "$LOG" | grep -v "Package WGCNA" | tee "output.log"
    

    每个命令的作用是什么?

    a) | -> 这会将前面命令的输出重定向为下一个命令的输入。它更像是一个连接器

    b) grep -> 通常用于搜索模式。在此示例中,我们将其与 -v 选项一起使用来进行反向匹配,即搜索除 Package WGCNA 之外的所有内容

    c) tee -> 这会将输出写入终端 + 还将其重定向到日志文件名,作为参数传递。如果不需要,您可以完全跳过此命令

    【讨论】:

    • 如果需要,您可以随时使用-E(用于正则表达式)或表达式组合进一步扩展 grep 以更好地控制过滤部分
    • 问题是添加到消息中的“审美字符”(我没有包含在原始问题中)。 '=' 和 '*' 被添加到文本中的框中,并且使用 grep 命令删除有点不靠谱。
    • 对于最终实现,我提前在 Rscript 中加载了 WGCNA,使用 capture.output() 将输出写入 temp-dirr 中的临时文件。必须包含 suppressMessages() 以排除写入终端/日志文件的 WGCNA 依赖项的加载消息。 capture.output(suppressMessages(library(WGCNA)))
    猜你喜欢
    • 1970-01-01
    • 2012-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多