【问题标题】:Why can't an executable find a shared library only when run as a http request为什么可执行文件只有在作为 http 请求运行时才能找到共享库
【发布时间】:2019-04-01 02:14:27
【问题描述】:

我有一个带有 shell_exec 调用的 php 文件。 shell_exec 函数运行一个 .sh 文件。

#!/bin/bash

filename=$(ls *.jpg -Art | tail -n 1)
codegen_dir=/usr/local/codegen/

cd "$codegen_dir"
out=$(./classifier /var/www/$filename)
echo $out

可执行的“分类器”存在于 codegen_dir 中,并具有 1 个共享库依赖项。该脚本从命令行正确运行。 php 文件也可以从命令行正确运行。但是,当我将 php 文件作为 http 请求运行时,我在 std_err 中得到以下信息:

"./classifier: 加载共享库时出错: libreader.so: 无法打开共享对象文件: 没有这样的文件或目录"

.so 文件与可执行文件位于同一目录中

我的 php 服务器根目录是:/var/www

  • 服务器根目录下的所有文件都有权限:-rwxrwxrwx 1 www-data www-data
  • “codegen_dir”中的所有文件都具有以下权限:-rwxrwxrwx 1 ubuntu www-data
  • 我可以读取 codegen_dir 中的其他文件

【问题讨论】:

  • 我们可以有./classifierhttpd.conf的代码吗?
  • 我没有对 httpd.conf 进行任何更改,也无法共享可执行文件的代码。但是,我可以澄清我的问题:它是一个可执行文件,只有一个共享库依赖项(.so 文件),如果有帮助的话
  • 加载程序从不检查当前目录中的共享对象,除非它通过 $LD_LIBRARY_PATH 明确指向。有关更多详细信息,请参见 ld.so(8) 手册页。您可以将共享库放在标准位置之一,请参阅 /etc/ld.so.conf。示例:/usr/local/lib/libreader.so
  • 重申:我能够在命令行上运行脚本,问题是当我从 http 请求触发它时。是的,我确实设置了 ld.so.conf

标签: php linux bash shell exec


【解决方案1】:

apache 用户可能无法访问共享库路径。您可以在 sudoers 文件中允许 apache 的分类器程序,并使用 sudo 以 apache 用户身份运行分类器应用程序

或者 通过更改权限使所有用户都可以访问共享库及其路径

out=$(sudo ./classifier /var/www/$filename)

尝试使用 apache 用户登录并运行上面的脚本或尝试访问共享库

su -s /bin/bash apache

【讨论】:

  • 如上所述,与共享库同目录的其他文件可以被apache用户读取
  • 尝试使用 apache 用户登录并运行以上脚本或尝试访问共享库
  • 我能够以 apache 用户的身份正确运行脚本,但不能以 http 请求的身份运行。我认为这是因为子进程(从 shell_exec 触发)无权访问 LD_LIBRARY_PATH。有没有办法解决这个问题?
  • 尝试在shell脚本顶部导出LD_LIBRARY_PATH
  • 在 shell 脚本顶部导出 LD_LIBRARY_PATH 是可行的,但是有没有更简洁的方法来做到这一点
猜你喜欢
  • 2017-06-18
  • 2014-01-14
  • 1970-01-01
  • 2019-08-03
  • 2012-08-13
  • 2018-10-10
  • 2019-11-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多