在 Ubuntu Linux 16.04 Lenovo Thinkstation 桌面上运行的 C# 可执行文件在哪里运行,这些可执行文件使用 DLLImport 的共享对象 (so's) 在运行时查找共享对象的源代码?即使共享对象 libxyz.so 与 C# 可执行文件的子目录位于同一子目录中,我发现有必要导出 LD_LIBRARY_PATH 以确保正确的 C# 可执行程序行为。为什么会这样呢?
我们注意到,在许多第三方Linux软件产品的安装过程中,安装程序或脚本会在子目录/usr/libx86_64-linux-gnu中找到libc.so.6,而不需要客户指定包含该子目录的LD_LIBRARY_PATH。为什么会这样?
另外,如果我们希望将 C# 可执行文件作为点按单一服务运行,我们如何全局指定 LD_LIBRARY_PATH,直到计算机重新启动,而不需要打开 Ubuntu Linux 16.04 终端?有没有比将 LD_LIBRARY_PATH 作为 envp 参数传递给 execle 更优雅的方法?
答案1
我将尝试为您回答这个问题的所有三个部分
【为什么】需要导出LD_LIBRARY_PATH以确保正确的C#可执行程序行为
安装程序或脚本设法在子目录 /usr/libx86_64-linux-gnu 中找到 libc.so.6,而不需要客户指定 LD_LIBRARY_PATH
链接库是从一组已知位置引用的。通常这些是系统目录,以便特权代码可以安全地使用它们(它们不能被用户覆盖)。
一旦你理解了这一点,你就会意识到已知位置的集合不能不包括.
。您可以通过检查文本文件来查看一组已知位置/etc/ld.so.conf
。如果您对其进行编辑,则必须运行ldconfig
以更新其相应的二进制数据库。
可以通过使用 的实例来扩展每个应用程序的已知位置集LD_LIBRARY_PATH
,该实例采用冒号分隔的目录列表进行搜索。如果你使用这个,内核会放弃程序的所有权限 - 所以你不能用它来欺骗passwd
或sudo
,例如。
我们如何全局指定 LD_LIBRARY_PATH,直到计算机重新启动 [...] 有没有比将 LD_LIBRARY_PATH 作为 envp 参数传递给 execle 更优雅的方法?
在全局范围内设置它是一个非常糟糕的主意,因为它会破坏sudo
、passwd
和其他特权程序。不过,我不明白为什么不能LD_LIBRARY_PATH
在每个应用程序的 shell 脚本中进行设置。您不需要将其作为“终端程序”启动,因为它不会向终端写入任何重要内容
#!/bin/bash
#
APP_DIR=/path/to/application
APP_DIR_LIB="$APP_DIR/lib"
APP_DIR_EXE="$APP_DIR/someprogram.exe"
export LD_LIBRARY_PATH="$APP_LIB_DIR"${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
exec "$APP_DIR_EXE" "$@"
echo "Ooops" >&2
exit 1
我已经使用了"$@"
这样的方式,传递给脚本的任何参数都将应用于可执行文件本身。
我不知道如何启动或停止单一服务,所以我无法帮助您了解具体细节。如果您更新您的问题,我会看看是否可以在此处添加任何内容。