257-Ubuntu的shiny app缺少字体怎么办?

刘小泽写于2022.7.2 记录自己从发现问题到解决问题的思路

我如何发现的问题?

最近偶然发现,之前部署在ubuntu服务器上的shiny app和本地显示的图片字体不一致,突然想到原因是服务器上可能没有本地电脑上的那些字体(比如常见的Arial),因此函数extrafont::font_import() 也无法导入默认的Arial画图字体

问题的关键是什么?

既然没有字体,那么关键就是给服务器装上这些字体,其实函数很简单,在本地操作也很简单:

extrafont::font_import()

但问题来了,大片的信息指向找不到这个字体,但很明显,这些字体就放在了usr/share/fonts下面的子目录:

尝试搜索

在extrafont包的GitHub论坛找到了讨论”No FontName. Skipping during font_import()“:https://github.com/wch/extrafont/issues/32

其中,大家一致提到可能的解决办法:

library(remotes)
remotes::install_version("Rttf2pt1", version = "1.3.8")

尝试解决

因为我的shiny app是部署在shiny用户下,因此也需要在这个用户下去安装这个包,但我发现这个包已经被装过了

# 看下版本
 packageVersion(Rttf2pt1)
# 1.3.10 (是最新版本)

只有降级才能解决问题

# 接下来直接在shiny用户下安装
remotes::install_version("Rttf2pt1", version = "1.3.8")

结果报错,提示gcc编译出了问题

尝试失败

接下来,我用了20分钟的时间,去探索如何在ubuntu上解决这个编译的问题,也尝试了如何直接用apt-get 来安装字体,结果都失败了

关于编译,我大概搜索了这些,但最终还是没能在shiny用户下取得成功:

关于apt-get,其实也只是想另辟蹊径,在:https://askubuntu.com/questions/651441/how-to-install-arial-font-and-other-windows-fonts-in-ubuntu,搜索到了:

sudo apt install ttf-mscorefonts-installer
sudo fc-cache -f
# After that, check with
fc-match Arial

我发现,这个命令可以运行成功,并且fc-match也有结果,那就更加说明服务器本地是存在这些字体的,只不过没办法将这些字体和R包extrafont关联起来

换个思路

搞shiny用户搞累了,我想直接试试root。如果连root都失败,我就要放弃了,毕竟字体这个事只是锦上添花

sudo -i 
R
# 同样去安装,竟然成功了
remotes::install_version("Rttf2pt1", version = "1.3.8")

也就是说,root可以调用编译的权限,但是shiny却不能

这里,我不再纠结如何切换编译权限的问题,而是:

既然root给我安好了1.3.8这个版本,那么我能不能直接给shiny用?

因此,我直接把root下的这个版本替换到shiny用户下,实现了”太子换狸猫“:

# 先看看各自的安装路径
.libPaths()
# shiny是第一个,root是第二个
# [1] "/home/shiny/R_Library"         "/usr/local/lib/R/site-library"
# [3] "/usr/lib/R/site-library"       "/usr/lib/R/library"

# 接下来直接替换
cp -r /usr/local/lib/R/site-library/Rttf2pt1/ /home/shiny/R_Library

等我切换回shiny后,再次查看版本,发现它成功更改为了1.3.8

到此,问题基本解决了

问题收尾

最后,就是加载字体了:

library(extrafont)
extrafont::font_import()
extrafont::loadfonts(quiet=TRUE)

导入了字体后,shiny app当然也就能识别了(别忘了重启shiny来更新这个功能),最后的图片字体也显示正常了

彩蛋

当然,解决这一个问题还不算完,举一反三:如何在ubuntu中下载字体呢?

# step1: Install cabextract, a tool needed to unpack self-extracting .exe archives:
sudo apt install cabextract
# step2: Download the font package
wget https://www.freedesktop.org/software/fontconfig/webfonts/webfonts.tar.gz
# step3: Unpack
tar -xzf webfonts.tar.gz
cd msfonts/
cabextract *.exe
# step4: Move the fonts to your user's directory for installing additional fonts
cp *.ttf *.TTF /YOUR_FONT_DIR/
Yunze Liu
Yunze Liu
Bioinformatics Sharer

Co-founder of Bioinfoplanet(生信星球)

Next
Previous

Related