【问题标题】:Libreoffice gives "Application Error" when called from R从 R 调用时,Libreoffice 给出“应用程序错误”
【发布时间】:2018-08-25 09:42:45
【问题描述】:

在 docker 容器中,我尝试使用 LibreOffice 将 XLSX 文件转换为 PDF。相关命令在命令行上运行,但在从 R 调用时失败并出现“应用程序错误”。我使用这个 Dockerfile 添加一些(根据我的经验任意)XLSX 文件:

FROM rocker/r-ver:3.4.3

RUN apt-get update \
 && apt-get install --yes --no-install-recommends \
    default-jre-headless libreoffice-calc \
 && apt-get clean \
 && rm -rf /var/lib/apt/lists/* \
 && echo /usr/lib/libreoffice/program > /etc/ld.so.conf.d/libreoffice.conf \
 && ldconfig

COPY foo.xlsx /tmp

(ldconfig 的诀窍来自 shared library issue with the system function in R.)

然后我可以在命令行上将 XLSX 文件转换为 PDF:

root@b395caeba33b:/# loffice --headless --convert-to pdf /tmp/foo.xlsx 
convert /tmp/foo.xlsx -> //foo.pdf using filter : calc_pdf_Export

但是,这在 R 中失败了:

> system("loffice --version")
LibreOffice 5.2.7.2 20m0(Build:2)

> system("loffice --headless --convert-to pdf /tmp/foo.xlsx")
convert /tmp/foo.xlsx -> //foo.pdf using filter : calc_pdf_Export
Application Error

如果我将使用 R 3.4.4 和 Debian testing/sid 的基本映像从 rocker/r-ver:3.4.3 更改为 rocker/r-base,结果只会略有变化:

> system("loffice --version")
LibreOffice 6.0.2.1.0 00m0(Build:1)

> system("loffice --headless --convert-to pdf /tmp/foo.xlsx")
Application Error

从 R 调用时,如何让 LibreOffice 将 XLSX 文件转换为 PDF?

【问题讨论】:

  • 发布了一个答案并解释了为什么它不起作用。请看一下

标签: r docker libreoffice


【解决方案1】:

我找到了一种解决方法,但我仍然对正确的解释感兴趣。这是我发现的:

  • 使用选项--security-opt seccomp:unconfined 启动docker 容器并安装strace
  • R内调用

    system("strace -f -o R.trace loffice --headless --convert-to pdf /tmp/foo.xlsx")
    
  • 生成的跟踪文件显示加载 libsal_textenclo.so 时出错。奇怪的是它在/usr/lib/x86_64-linux-gnu 中搜索库,即使ldconfig 知道在哪里可以找到它:

    root@1519f52c05e0:/# grep libsal R.trace 
    257   open("/usr/lib/x86_64-linux-gnu/libsal_textenclo.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
    root@1519f52c05e0:/# ldconfig -p | grep libsal
        libsal_textenclo.so (libc6,x86-64) => /usr/lib/libreoffice/program/libsal_textenclo.so
    
  • LD_LIBRARY_PATH 设置为包含/usr/lib/libreoffice/program不能解决问题。

    root@4a235dfa08e3:~# export LD_LIBRARY_PATH=/usr/lib/libreoffice/program
    root@4a235dfa08e3:~# Rscript -e 'system("loffice --headless --convert-to pdf /tmp/foo.xlsx")'
    Application Error
    
  • 我当前的解决方法是在 R 会话中设置 LD_LIBRARY_PATH

    > Sys.setenv(LD_LIBRARY_PATH="/usr/lib/libreoffice/program")
    > system("loffice --headless --convert-to pdf /tmp/foo.xlsx")
    convert /tmp/foo.xlsx -> //foo.pdf using filter : calc_pdf_Export
    Overwriting: //foo.pdf
    

【讨论】:

  • 第四点不起作用,如何设置LD_LIBRARY_PATH?
  • @Robert Via export 在容器内。见编辑。使用docker run -e LD_LIBRARY_PATH=/usr/lib/libreoffice/program ... 会得到相同的结果。
  • 尝试在/etc/ld.so.conf.d/local-libreoffice.conf(或其他名称)中添加该目录。
  • @DirkEddelbuettel 这已经在 Dockerfile 中完成了:&& echo /usr/lib/libreoffice/program > /etc/ld.so.conf.d/libreoffice.conf 。否则loffice --version 将不起作用。
  • 嗯,我明白了。这很奇怪。
【解决方案2】:

由于环境差异而发生此问题。当您通过system 运行env 命令时

> system('env')
R_UNZIPCMD=/usr/bin/unzip
HOSTNAME=da4d504ddcb1
LD_LIBRARY_PATH=/usr/local/lib/R/lib:/usr/local/lib:/usr/lib/x86_64-linux-gnu:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server
SHLVL=0
HOME=/root
R_LIBS_SITE=
R_BROWSER=xdg-open
PAGER=/usr/bin/pager
R_VERSION=3.4.3
BUILD_DATE=
R_SYSTEM_ABI=linux,gcc,gxx,gfortran,?
TAR=/bin/tar
R_LIBS_USER=/usr/local/lib/R/site-library
TERM=xterm
COLUMNS=200
R_ARCH=
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
R_BZIPCMD=/bin/bzip2
R_INCLUDE_DIR=/usr/local/lib/R/include
R_SESSION_TMPDIR=/tmp/RtmpJsaXba
LANG=en_US.UTF-8
R_GZIPCMD=/bin/gzip
SED=/bin/sed
LN_S=ln -s
R_PDFVIEWER=/usr/bin/xdg-open
R_TEXI2DVICMD=/usr/bin/texi2dvi
R_HOME=/usr/local/lib/R
R_PRINTCMD=/usr/bin/lpr
R_DOC_DIR=/usr/local/lib/R/doc
R_LIBS=/usr/local/lib/R/site-library:/usr/local/lib/R/library:/usr/lib/R/library
LC_ALL=en_US.UTF-8
R_SHARE_DIR=/usr/local/lib/R/share
PWD=/
R_ZIPCMD=/usr/bin/zip
R_PLATFORM=x86_64-pc-linux-gnu
R_PAPERSIZE=letter
LINES=50
MAKE=make
R_RD4PDF=times,inconsolata,hyper
EDITOR=vi

您可以看到默认的R 具有一组环境变量,其中一个是LD_LIBRARY_PATH

> system('loffice --headless --convert-to pdf /tmp/foo.xlsx')
Application Error
> system('LD_LIBRARY_PATH= loffice --headless --convert-to pdf /tmp/foo.xlsx')
convert /tmp/foo.xlsx -> //foo.pdf using filter : calc_pdf_Export

将其删除即可。它在 bash 中起作用的原因是因为默认的环境变量集很小

root@5c5bbcfcebf2:/# env
LC_ALL=en_US.UTF-8
LANG=en_US.UTF-8
HOSTNAME=5c5bbcfcebf2
PWD=/
HOME=/root
R_VERSION=3.4.3
BUILD_DATE=
TERM=xterm
SHLVL=1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
_=/usr/bin/env

当您从 bash 启动 r 而不是 R

root@5c5bbcfcebf2:/# r -i
system('env')
R_UNZIPCMD=/usr/bin/unzip
HOSTNAME=5c5bbcfcebf2
SHLVL=1
R_INSTALL_PKG=littler
HOME=/root
R_ENVIRON=
R_LIBS_SITE=
R_BROWSER=xdg-open
PAGER=/usr/bin/pager
R_VERSION=3.4.3
BUILD_DATE=
R_SYSTEM_ABI=linux,gcc,gxx,gfortran,?
R_PROFILE_USER=
TAR=/bin/tar
_=/usr/local/bin/r
R_LIBS_USER=/usr/local/lib/R/site-library
TERM=xterm
R_ARCH=
R_PAPERSIZE_USER=letter
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
R_BZIPCMD=/bin/bzip2
R_INCLUDE_DIR=/usr/local/lib/R/include
R_SESSION_TMPDIR=/tmp
R_OSTYPE=unix
LANG=en_US.UTF-8
R_CMD=/usr/local/lib/R/bin/Rcmd
R_DEFAULT_PACKAGES=NULL
R_PACKAGE_NAME=littler
R_GZIPCMD=/bin/gzip
LN_S=ln -s
SED=/bin/sed
R_PDFVIEWER=/usr/bin/xdg-open
R_PROFILE=
R_ENVIRON_USER=
R_TEXI2DVICMD=/usr/bin/texi2dvi
R_HOME=/usr/local/lib/R
R_PRINTCMD=/usr/bin/lpr
R_DOC_DIR=/usr/local/lib/R/doc
R_LIBS=/usr/local/lib/R/site-library:/usr/local/lib/R/library:/usr/lib/R/library
LC_ALL=en_US.UTF-8
PWD=/
R_SHARE_DIR=/usr/local/lib/R/share
R_ZIPCMD=/usr/bin/zip
R_PAPERSIZE=letter
R_PLATFORM=x86_64-pc-linux-gnu
MAKE=make
R_RD4PDF=times,inconsolata,hyper
EDITOR=vi

在使用 r -i 从 bash 启动的交互式 shell 中

system('LD_LIBRARY_PATH= loffice --headless --convert-to pdf /tmp/foo.xlsx')
convert /tmp/foo.xlsx -> //foo.pdf using filter : calc_pdf_Export

system('loffice --headless --convert-to pdf /tmp/foo.xlsx')
convert /tmp/foo.xlsx -> //foo.pdf using filter : calc_pdf_Export
Overwriting: //foo.pdf

在您的案例中,是从父级继承的子进程环境导致问题

【讨论】:

  • 谢谢。根据您的回答,我发现如果 /usr/lib/x86_64-linux-gnuLD_LIBRARY_PATH 中,即使在 bash 中调用,LibreOffice 也会产生此错误。这不是默认的,但是 R 添加了这个目录。 LibreOffice为什么会出现这个问题还是有点奇怪。
  • 可能是某个库从该文件夹加载并且与 R 运行时不兼容。实际上知道这需要更多的调查时间,这似乎不值得付出努力
猜你喜欢
  • 2015-07-19
  • 1970-01-01
  • 2013-01-03
  • 2017-09-21
  • 1970-01-01
  • 2018-11-09
  • 2019-08-20
  • 2014-06-11
  • 1970-01-01
相关资源
最近更新 更多