如何在callr::r_bg中重定向stderr到文件且不锁定日志文件
解决Windows下callr::r_bg重定向stderr到文件不锁定的问题
方案1:借助Windows cmd命令行重定向
Windows系统中,callr默认的文件重定向会以独占模式打开文件,导致进程运行期间无法读取。通过让r_bg调用cmd.exe来处理stderr重定向,可绕过这个限制——cmd的2>>追加重定向会以共享模式打开文件,允许实时查看内容。
示例代码:
library(callr) # 定义你的长时间运行函数 long_running_func <- function() { library(cli) for (i in 1:10) { cli_alert_warning("这是第 {i} 条stderr输出", .envir = environment()) Sys.sleep(2) } } # 将函数写入临时R脚本 script_path <- tempfile(fileext = ".R") writeLines( 'library(cli); long_running_func <- function() { for (i in 1:10) { cli_alert_warning("这是第 {i} 条stderr输出", .envir = environment()); Sys.sleep(2) } }; long_running_func()', script_path ) # 构造cmd命令,实现stderr追加到日志文件 log_file <- "stderr_log.txt" cmd <- sprintf('cmd.exe /c "Rscript %s 2>> %s"', shQuote(normalizePath(script_path)), shQuote(normalizePath(log_file))) # 后台启动进程 proc <- r_bg(cmd, command = TRUE) # 此时可直接打开stderr_log.txt实时查看输出
方案2:直接使用processx自定义文件打开模式
callr底层依赖processx包,直接使用processx的process类,可指定文件打开模式和关闭文件锁定,避免独占问题。
示例代码:
library(processx) log_file <- "stderr_log.txt" # 先创建空日志文件,避免进程启动时报错 if (!file.exists(log_file)) file.create(log_file) # 启动后台进程,自定义stderr的文件处理 proc <- process$new( command = R.home("bin/Rscript"), args = c("-e", 'library(cli); for (i in 1:10) { cli_alert_warning("第 {i} 条输出"); Sys.sleep(2) }'), stderr = file(log_file, open = "ab", blocking = FALSE), file_locking = FALSE ) proc$start()
关键说明
- 方案1无需修改原函数逻辑,借助系统命令行的重定向特性即可解决锁定问题,适合快速实现。
- 方案2更灵活,直接控制进程的文件IO参数,适合需要精细控制的场景。
内容的提问来源于stack exchange,提问作者thothal
相关产品推荐
相关产品推荐

