解决Linux系统升级后R包加载失败的问题
2020-01-02 20:30
本文共约 642 字
预计阅读时间约 2 分钟
问题遭遇
今天升级了Linux系统的一堆底层运行时库,结果发现R包RProtoBuf加载失败了,报出如下错误:
1> library(RProtoBuf)
2Error: package or namespace load failed for ‘RProtoBuf’ in dyn.load(file, DLLpath = DLLpath, ...):
3 unable to load shared object '/home/yanll/R/x86_64-pc-linux-gnu-library/3.6/RProtoBuf/libs/RProtoBuf.so':
4 libprotobuf.so.19: cannot open shared object file: No such file or directory过去遇到这种问题时,我通常的解决方法,就是重新安装相应的R包,就可解决问题:
1> install.package("RProtoBuf")不过,有时候涉及很多包都受到影响,就需要逐个重新编译。但因为不知道到底有多少包需要重新安装,于是整个过程可能就需要手工进行多次尝试才能完全解决。
这个问题,并不能通过如下方式解决:
1> BiocManager::install()因为该命令只能根据R包之间的版本关系来进行更新,而并不能检查到“unable to load shared object”的错误。
问题解决
为此,我尝试了如下的bash命令,用来列举到底有哪些动态库(*.so文件)出现了依赖问题,预期通过重新安装它们所属的R包即可:
1$ Rscript -e 'cat(.libPaths(), sep = "\n")' \
2 | while read d; do \
3 ( \
4 cd $d; \
5 find -type f -name '*.so' -executable \
6 | while read f; do \
7 if [ "$(ldd $f | grep "not found" | wc -l)" -gt 0 ]; then \
8 echo "$d/$f"; \
9 fi; \
10 done \
11 ) \
12 done如下命令,则将这些输出.so文件所属包名(上级目录名)取出,用awk构造了R语言的安装命令,提交给Rscript进行安装:
1$ Rscript -e 'cat(.libPaths(), sep = "\n")' \
2 | while read d; do \
3 ( \
4 cd $d; \
5 find -type f -name '*.so' -executable \
6 | while read f; do \
7 if [ "$(ldd $f | grep "not found" | wc -l)" -gt 0 ]; then \
8 echo $f; \
9 fi; \
10 done \
11 ) \
12 done \
13 | cut -d/ -f2 \
14 | awk '{print"install.packages(\""$0"\")"}' \
15 | Rscript /dev/stdin最终,问题得以解决。