防止 R 中的 .libPaths() 解析符号链接

Prevent .libPaths() in R from resolving symlinks

我有两个几乎相同的系统。我在 /export/apps/ 中的 system1(远程测试环境)中安装软件,然后将文件 rsync 到其 /export/apps 中的 system2。由于文件系统的原因,/export/ 在每个系统上实际上是一个 symlink。这通常适用于大多数程序 b/c,任何硬烘焙路径都包含 symlink 并且 symlink 下的文件结构是相同的。所以

系统 1 : /export/ -> /gpfs0/remote-test/export

系统 2 : /export/ -> /gpfs0/export

然而,当我在 R 中设置 .libPaths 时,R 'helpfully' 解析了 symlinks。我非常怀疑,当我将其 rsync 到 system2 时,那些已解析的 symlinks 将破坏已安装的软件。例如。 (在 R/4.0.0)

> .libPaths = .libPaths("/export/apps/opt/monocle3/1.0.0/")
> .libPaths()
[1] "/gpfs0/remote-test/export/apps/opt/monocle3/1.0.0"
[2] "/gpfs0/export/apps/easybuild/software/R/4.0.0-foss-2020a/lib64/R/library"

问题 :

有没有办法阻止 .libPaths() 将符号 link /export/ 解析为其完整路径?

.libPaths()函数非常简单:

> .libPaths
function (new, include.site = TRUE) 
{
    if (!missing(new)) {
        new <- Sys.glob(path.expand(new))
        paths <- c(new, if (include.site) .Library.site, .Library)
        paths <- paths[dir.exists(paths)]
        .lib.loc <<- unique(normalizePath(paths, "/"))
    }
    else .lib.loc
}

您的符号链接正在接近尾声的 normalizePath(paths) 调用中解析。所以你的问题的答案是“不,你不能告诉 .libPaths() 不解析符号链接”。

我想你可以自己写一个不调用 normalizePath() 的版本,但这似乎很冒险:R 很可能假设它已经发生了。

我还假设使用 rsync 将已安装的包从一个位置移动到另一个位置可能会破坏具有复杂配置的包中的某些内容。允许带有 StagedInstall: FALSE 的包假设这永远不会发生。

我认为您只需要在 system2 上再次安装这些软件包,以确保它们针对该系统进行了正确配置。

我继续在 /gpfs0/remote-test/export/apps/opt/monocle3/1.0.0 的远程测试环境 (system1) 上安装了 R 包。它在 system1 上工作(至少我可以加载库)。

然后我将安装的软件包 rsync 到 system2 上的 /gpfs0/export/apps/opt/monocle3/1.0.0,它也在那里工作。

我确实对共享库进行了一些检查(即 find . -name "*.so" -print | xargs -I var grep -in remote-test var),并且字符串 remote-test hard-baked 进入了三个共享库。

这次我似乎逃过了一劫(请参阅 user2554330 的 了解为什么它将来可能不起作用)。据我所知,我没有受到任何 hard-baked 路径的伤害。在这种情况下,我可以移动 R 个库而不破坏任何东西。