lnmp环境调用unoconv报错

遇到问题

某业务需要将mime非application/msword的文件转成doc格式,在网上查询了一下,unoconv可以,安装好后,通过web的url访问后发现居然报错。

PHP代码

$cmd = "unoconv --connection \"socket,host=127.0.0.1,port=8100;urp;StarOffice.ComponentContext\" -f doc -o {$file} {$textfile}"
exec($cmd,$arrRet);

报错信息如下

Array
(
[0] => Traceback (most recent call last):
[1] => File “/usr/bin/unoconv”, line 993, in
[2] => office_environ(of)
[3] => File “/usr/bin/unoconv”, line 150, in office_environ
[4] => os.environ[‘PATH’] = os.path.join(office.basepath, ‘program’) + os.pathsep + os.environ[‘PATH’]
[5] => File “/usr/lib64/python2.6/UserDict.py”, line 22, in getitem
[6] => raise KeyError(key)
[7] => KeyError: ‘PATH’
)

环境变量PATH找不到。
将命令放到命令行上执行,居然可以执行成功。

思考过程

  • 权限问题:php-fpm执行用户是www,命令行运行是root用户。(事后感觉这种思考有点浅陋,因为后续查看www用户的变量是包含PATH的)
  • 命令行与web到底有何不同?

解决过程

针对权限问题

在命令行上使用 sudo -uwww unoconv …,居然可以执行成功。
各种百度搜索有关python的env的相关知识,发现env[‘PATH’]是用户变量的内容,去服务器上查了下www用户的PATH,是定义了的。查询了下python中设置环境变量的内容,然后莫名奇妙的想到一种思路:写一个python脚本,先临时修改变量,再执行unoconv;最后php通过exec执行这个python脚本

python

import os
os.environ['PATH'] = ''
disfile = ''
sourcefile = ''
cmd = 'unoconv --connection "socket,host=127.0.0.1,port=8100;urp;StarOffice.ComponentContext" -f doc -o {} {}'.format(disfile,sourcefile)
os.system(cmd)

php脚本

exec('python脚本路径',$arrRet);

发现这样可以。但是为什么命令行和web环境不一样,web环境为什么获取不到path,这个一直想不通,也从来没有遇到过。下面深入思考这个问题

命令行与web的不同

命令行是在终端直接执行命令,而web方式是通过web服务器->cgi->php解释器来执行命令的,我上面命令行是直接执行的命令,web还要经过这3到坎。

首先排除是不是php解释器的问题。在命令行通过php解释器执行unoconv

php 第一段代码

结果发现命令可以生成

排除是不是cgi的问题,打开lnmp的cgi是php-fpm,打开php-fpm的配置文件,看到以下说明

; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
; the current environment.
; Default Value: clean env
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp

这就应该是问题所在吧,好激动啊。
打开注释,重启php-fpm,web访问第一段代码,成功

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值