如何从 bash 更改库包含二进制文件的路径?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4896017/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 23:24:15  来源:igfitidea点击:

How to change the library include path of a binary from bash?

c++linuxbashinclude-pathkde4

提问by augustin

I have a software properly installed on Kubuntu.

我在 Kubuntu 上正确安装了一个软件。

Now, I am patching and testing some of its libraries.

现在,我正在修补和测试它的一些库。

How can I start the software from bash so that it loads my patched libraries instead of the official libs?

如何从 bash 启动软件,以便它加载我打过补丁的库而不是官方库?

e.g.:
the official libs are locate in /usr/lib/
my patch libraries (used during test development) are in /home/user/dev/lib/

例如:
官方库位于 /usr/lib/
我的补丁库(在测试开发期间使用)位于 /home/user/dev/lib/

I tried:

我试过:

$ set LD_LIBRARY_PATH=/home/user/dev/lib/  
$ binary_app &

but to no avail.

但无济于事。

I'd prefer a solution that can be set from the bash, but if it's not possible, I could also modify the cmake file of this C++ software.

我更喜欢可以从 bash 设置的解决方案,但如果不可能,我也可以修改这个 C++ 软件的 cmake 文件。

The aim is to allow me to easily start the application either with the vanilla libs, or with my patched libs to see the differences.

目的是让我可以轻松地使用 vanilla 库或修补过的库启动应用程序以查看差异。

Edit: it's a KDE .so file

编辑:这是一个 KDE .so 文件

The library I am testing is a KDE4 library. The official lib is in /usr/lib/kde4/ . In that directory, none of the library start with the libprefix.

我正在测试的库是一个 KDE4 库。官方库在 /usr/lib/kde4/ 中。在该目录中,没有任何库以lib前缀开头。

Whether I do:

我是否:

/lib/ld-linux-x86-64.so.2 --list  --library-path PATH EXEC  

or

或者

ldd EXEC  

The library is not listed at all.

图书馆根本没有列出。

On the other hand, if if move the original library away from /usr/lib/kde4/, the application starts but the corresponding functionality is missing.

另一方面,如果将原始库从 /usr/lib/kde4/ 移开,则应用程序启动但缺少相应的功能。

Are KDE4 libraries loaded in a specific way? Maybe the variable to set is different...

KDE4 库是否以特定方式加载?也许要设置的变量不同......

Edit 2

编辑 2

All the answers are good and useful... unfortunately, it turned out that the problem does not appear to be related to the lib path setting. I'm dealing with a plugin architecture and the .so loading path appears to be hard-coded somewhere in the application. I need to spend more time within the source code to understand what's happening... Thanks and +1 to all.

所有的答案都很好而且很有用……不幸的是,结果证明问题似乎与 lib 路径设置无关。我正在处理一个插件架构,而 .so 加载路径似乎是在应用程序的某个地方硬编码的。我需要在源代码中花更多的时间来了解正在发生的事情......感谢并为所有人 +1。

回答by Jan de Vos

From 'man bash':

来自“男人 bash”:

When a simple command other than a builtin or shell function is to be executed, it is invoked in a separate execution environment that consists of the following. Unless otherwise noted, the values are inherited from the shell.

[....]

· shell variables and functions marked for export, along with variables exported for the command, passed in the environment

当要执行除内置函数或 shell 函数之外的简单命令时,它会在包含以下内容的单独执行环境中调用。除非另有说明,否则这些值都是从 shell 继承的。

[....]

· 标记为导出的shell变量和函数,以及为命令导出的变量,在环境中传递

You need to 'export' a variable if it is to be seen by programs you execute.

如果您要执行的程序看到它,您需要“导出”一个变量。

However, you can also try the following:

但是,您也可以尝试以下操作:

/lib/ld-linux.so.2 --library-path PATH EXECUTABLE

/lib/ld-linux.so.2 --library-path 可执行路径

See http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html

http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html

回答by Karl Bielefeldt

Try export LD_LIBRARY_PATH=...instead of set.

尝试export LD_LIBRARY_PATH=...而不是设置。

回答by rve

I already put this in a comment but after thinking about it I think the best way to do this (using a different library just for testing/debugging) is using LD_PRELOAD, see What is the LD_PRELOAD trick?

我已经把它放在评论中,但经过思考,我认为最好的方法(使用不同的库仅用于测试/调试)是使用LD_PRELOAD,请参阅什么是 LD_PRELOAD 技巧?

From the man page:

从手册页:

LD_PRELOAD

A whitespace-separated list of additional, user-specified, ELF shared libraries to be loaded before all others. This can be used to selectively override functions in other shared libraries. For set-user-ID/set-group-ID ELF binaries, only libraries in the standard search directories that are also set-user-ID will be loaded.

LD_PRELOAD

要在所有其他库之前加载的其他用户指定的 ELF 共享库的空白分隔列表。这可用于选择性地覆盖其他共享库中的函数。对于 set-user-ID/set-group-ID ELF 二进制文件,只会加载标准搜索目录中也是 set-user-ID 的库。

Update:

更新:

After the updated question it seems the application is using dlopento open the library using a absolute path. I don't think you can do anything about it. See man dlopen

在更新的问题之后,应用程序似乎正在使用dlopen绝对路径打开库。我认为你对此无能为力。看man dlopen

Update2:

更新2:

Maybe there is something you can do: you might be able to LD_PRELOADyour own dlopenfunction which modifies the path to your own library...

也许您可以做些什么:您可以使用LD_PRELOAD自己的dlopen函数来修改您自己的库的路径...

回答by rve

Isn't you app setuid or setgid by chance? In this case LD_LIBRARY_PATH will be ignored.

你不是偶然的应用 setuid 或 setgid 吗?在这种情况下,LD_LIBRARY_PATH 将被忽略。

回答by KitsuneYMG

Put everything on one line:

将所有内容放在一行:

LD_LIBRARY_PATH=foo binary_app&