LD_LIBRARY_PATH配置不生效
LIBRARY_PATH与LD_LIBRARY_PATH
-
LIBRARY_PATH
为编译链接时查找动态链接库使用的路径-
gcc 文件 -lpthread
这里可以不跟动态链接库路径,若动态库在/lib
或/usr/
lib中,可以不带动态库路径 -
gcc 文件 -lmul
这里的mul
动态库是自己的动态库,若没有放在/lib
或/usr/
lib中,也没有配置LIBRARY_PATH
会提示找不到。gcc UTSP16.c -o U16 -lmul /usr/bin/ld: 找不到 -lmul collect2: error: ld returned 1 exit status
gcc
使用-I
指定动态库头文件目录,-L
指定动态库路径,就可以链接到gcc UTSP16.c -o U16 -lmul -I /home/kylin/Multiple/lib/ -L /home/kylin//Multiple/lib/
-
将动态库路径配置到
LIBRARY_PATH
中,gcc
也可以链接到
-
-
LD_LIBRARY_PATH
为程序运行时查找动态链接库使用的路径运行二进制文件时,动态链接库的查找路径
1、编译目标代码时指定的动态库搜索路径:用选项-Wl,rpath和include指定的动态库的搜索路径,比如gcc -Wl,-rpath,include -L. -ldltest hello.c,在执行文件时会搜索路径`./include`; 2、环境变量LD_LIBRARY_PATH(多个路径用冒号分割); 3、在 /etc/ld.so.conf.d/ 目录下的配置文件指定的动态库绝对路径(通过ldconfig生效,一般是非root用户时使用); 4、gcc默认动态库目录:/lib:/usr/lib:usr/lib64:/usr/local/lib等。
问题复现
使用ldd -d
命令查看程序UTSP16
的动态库,可以看到libmul.so => /usr/lib/libmul.so (0x00007fe5131af000)
kylin@Kylin:~/Multiple/test$ ldd -d UTSP16
linux-vdso.so.1 => (0x00007ffef7af2000)
libmul.so => /usr/lib/libmul.so (0x00007fe5131af000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe512de5000)
/lib64/ld-linux-x86-64.so.2 (0x00005576174e5000)
使用rm删除/usr/lib/
中关于libmul
相关的软连接与库。使用ldd -d
查看发现libmul.so => not found
,而后运行UTSP16
。
kylin@Kylin:~/Multiple/test$ ldd -d UTSP16
linux-vdso.so.1 => (0x00007ffce35f7000)
libmul.so => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f53f865b000)
/lib64/ld-linux-x86-64.so.2 (0x000055e36e152000)
kylin@Kylin:~/Multiple/test$ ./UTSP16
./UTSP16: error while loading shared libraries: libmul.so: cannot open shared object file: No such file or directory
/etc/profile
加入export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/kylin/Multiple/lib
,执行source /etc/profile
,运行UTSP16
,发现运行时依然找不到动态库,配置无效。
kylin@Kylin:~/Multiple/test$ ldd -d UTSP16
linux-vdso.so.1 => (0x00007ffce35f7000)
libmul.so => not found 即使配置了LD_LIBRARY_PATH,执行`source /etc/profile`还是没有找到
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f53f865b000)
/lib64/ld-linux-x86-64.so.2 (0x000055e36e152000)
kylin@Kylin:~/Multiple/test$ ./UTSP16
./UTSP16: error while loading shared libraries: libmul.so: cannot open shared object file: No such file or directory
分析1:是否执行source /etc/profile
输出$LD_LIBRARY_PATH
的值,发现有内容,且是自己当时的配置。
kylin@Kylin:~/Multiple/test$ echo $LD_LIBRARY_PATH
:/home/kylin/Multiple/lib
分析2:LD_LIBRARY_PATH
中配置的目录是否正确
echo $LD_LIBRARY_PATH
查看配置,ll /home/kylin/Multiple/lib
查看路径下是否存在动态共享库,发现存在-rwxr-xr-x 1 root root 52848 4月 8 10:44 libmul.so.1*
,说明配置的共享库路径是对的。
kylin@Kylin:~/Multiple/test$ echo $LD_LIBRARY_PATH
:/home/kylin/Multiple/lib
kylin@Kylin:~/Multiple/test$ ll /home/kylin/Multiple/lib
总用量 212
drwxrwxr-x 3 kylin kylin 4096 4月 8 10:44 ./
drwxrwxr-x 7 kylin kylin 4096 4月 3 10:13 ../
-rw-r--r-- 1 root root 40320 4月 8 10:44 cJSON.o
-rw-r--r-- 1 kylin kylin 10396 4月 3 10:56 common.c
-rw-rw-r-- 1 kylin kylin 113 4月 3 10:56 common.d
-rw-r--r-- 1 kylin kylin 3627 4月 3 10:56 common.h
-rw-r--r-- 1 root root 8704 4月 8 10:44 common.o
drwxrwxr-x 2 kylin kylin 4096 4月 3 10:13 json/
-rw-r--r-- 1 root root 13248 4月 8 10:44 libmul.a
-rwxr-xr-x 1 root root 52848 4月 8 10:44 libmul.so.1* 只有共享库,没有共享库的软连接
-rw-r--r-- 1 kylin kylin 904 4月 3 10:56 Makefile
-rw-rw-r-- 1 kylin kylin 10404 4月 3 10:56 mulserv.c
-rw-rw-r-- 1 kylin kylin 194 4月 3 10:56 mulserv.d
-rw-rw-r-- 1 kylin kylin 4859 4月 3 10:56 mulserv.h
-rw-r--r-- 1 root root 12968 4月 8 10:44 mulserv.o
-rw-rw-r-- 1 kylin kylin 2606 4月 3 10:56 mulswitch.c
-rw-rw-r-- 1 kylin kylin 162 4月 3 10:56 mulswitch.d
-rw-rw-r-- 1 kylin kylin 830 4月 3 10:56 mulswitch.h
-rw-r--r-- 1 root root 2272 4月 8 10:44 mulswitch.o
分析3:LD_LIBRARY_PATH
中配置的目录,里面的动态库是否创建了软连接,若共享库没有创建软连接,也会找不到。
使用ll /home/kylin/Multiple/lib
查看路径下是否存在动态共享库,发现只存在-rwxr-xr-x 1 root root 52848 4月 8 10:44 libmul.so.1*
,而没有libmul.so.1
的软连接。
使用ln -s ../lib/libmul.so.1 ../lib/libmul.so
为libmul.so.1
创建软连接。
kylin@Kylin:~/Multiple/test$ ln -s ../lib/libmul.so.1 ../lib/libmul.so
kylin@Kylin:~/Multiple/test$ ll /home/kylin/Multiple/lib
总用量 212
drwxrwxr-x 3 kylin kylin 4096 4月 8 13:39 ./
drwxrwxr-x 7 kylin kylin 4096 4月 3 10:13 ../
-rw-r--r-- 1 root root 40320 4月 8 10:44 cJSON.o
-rw-r--r-- 1 kylin kylin 10396 4月 3 10:56 common.c
-rw-rw-r-- 1 kylin kylin 113 4月 3 10:56 common.d
-rw-r--r-- 1 kylin kylin 3627 4月 3 10:56 common.h
-rw-r--r-- 1 root root 8704 4月 8 10:44 common.o
drwxrwxr-x 2 kylin kylin 4096 4月 3 10:13 json/
-rw-r--r-- 1 root root 13248 4月 8 10:44 libmul.a
lrwxrwxrwx 1 kylin kylin 18 4月 8 13:39 libmul.so -> ../lib/libmul.so.1* 刚创建的软连接
-rwxr-xr-x 1 root root 52848 4月 8 10:44 libmul.so.1* 共享库
-rw-r--r-- 1 kylin kylin 904 4月 3 10:56 Makefile
-rw-rw-r-- 1 kylin kylin 10404 4月 3 10:56 mulserv.c
-rw-rw-r-- 1 kylin kylin 194 4月 3 10:56 mulserv.d
-rw-rw-r-- 1 kylin kylin 4859 4月 3 10:56 mulserv.h
-rw-r--r-- 1 root root 12968 4月 8 10:44 mulserv.o
-rw-rw-r-- 1 kylin kylin 2606 4月 3 10:56 mulswitch.c
-rw-rw-r-- 1 kylin kylin 162 4月 3 10:56 mulswitch.d
-rw-rw-r-- 1 kylin kylin 830 4月 3 10:56 mulswitch.h
-rw-r--r-- 1 root root 2272 4月 8 10:44 mulswitch.o
在创建完共享库的软连接后,使用ldd -d UTS16
查看,发现已经可以找到了,LD_LIBRARY_PATH
的配置生效
kylin@Kylin:~/Multiple/test$ ldd -d UTSP16
linux-vdso.so.1 => (0x00007ffeab7f9000)
libmul.so => /home/kylin/Multiple/lib/libmul.so (0x00007f3de2d7e000) 这里不再是not found,而是刚创建的软连接
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3de29a0000)
/lib64/ld-linux-x86-64.so.2 (0x00005569ec01b000)
分析4:用户登录才执行/etc/profile
(直接运行程序可以,sudo
运行程序找不到共享库)
查看现象:ldd -d /usr/bin/mulproc
与sudo ldd -d /usr/bin/mulproc
/etc/profile
加入export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/kylin/Multiple/lib
当前用户为kylin
,输出$LD_LIBRARY_PATH
kylin@kylin-X280:~$ echo $LD_LIBRARY_PATH
:/home/kylin/Multiple/lib/
kylin@kylin-X280:~$
使用su
进入root
,输出$LD_LIBRARY_PATH
为空。直接执行mulproc
是可以找到共享库,在kylin
用户下使用sudo
执行mulproc
是找不到共享库的。
root@kylin-X280:/home/kylin# echo $LD_LIBRARY_PATH
root@kylin-X280:/home/kylin#
-
使用
ldd -d /usr/bin/mulproc
查看,发现libmul.so => /home/kylin/Multiple/lib/libmul.so (0x00007f324700a000)
kylin@kylin-X280:~$ ldd -d /usr/bin/mulproc linux-vdso.so.1 (0x00007ffc797bf000) librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f324703b000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f3247018000) libmul.so => /home/kylin/Multiple/lib/libmul.so (0x00007f324700a000) 说明配置成功 libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3246e19000) /lib64/ld-linux-x86-64.so.2 (0x00007f3247070000)
-
使用
sudo ldd -d /usr/bin/mulproc
查看,发现libmul.so => not found
,可见配置对kylin
用户生效,对root
没有生效。kylin@kylin-X280:~$ sudo ldd -d /usr/bin/mulproc linux-vdso.so.1 (0x00007ffca98df000) librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f7811634000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f7811611000) libmul.so => not found 这时又找不到了 libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7811420000) /lib64/ld-linux-x86-64.so.2 (0x00007f7811669000) undefined symbol: already_running (/usr/bin/mulproc)
分析原因:/etc/profile
的执行过程
/etc/profile
与登录用户有关,每次用户登录才会执行。若没有用户登录,却又要运行相关程序,无法找到该环境变量。sudo
执行,使用的环境变量只是继承了前面用户env
的环境变量,使用env
查看环境变量,并没有export出来的LD_LIBRARY_PATH
。所以找不到LD_LIBRARY_PATH
。- 登录的用户是
kylin
,使用sudo
、su
,su root
都是不会执行/etc/profile
,找不到LD_LIBRARY_PATH
。 - 使用
su
或su root
也只是切换用户,并不会执行/etc/profile
,使用su -root
登录才会执行/etc/profile
。
解决方法:将LD_LIBRARY_PATH
放入/etc/environment
文件中
/etc/environment
的执行与用户登录无关,在/etc/environment
中加入LD_LIBRARY_PATH="/home/kylin/Multiple/lib"
kylin@kylin-X280:~$ cat /etc/environment
LD_LIBRARY_PATH="/home/kylin/Multiple/lib"
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
重启后,使用ldd -d /usr/bin/mulproc
与sudo ldd -d /usr/bin/mulproc
查看,都可以看到libmul.so => /home/kylin/Multiple/lib/libmul.so (0x00007f324700a000)
。
若还是不行,网上说,同时编辑
/etc/X11/Xsession.options
文件,将use-ssh-agent
更改为no-use-ssh-agent
分析5:Linux service
无法使用系统环境变量问题
查看现象:service启动失败,找不到共享库
在/etc/environment
或/etc/profile
中配置了LD_LIBRARY_PATH
,使用echo $LD_LIBRARY_PATH
可以看到值,使用ldd -d
也可以配置的共享库。但是service启动失败,找不到共享库。
例如执行mulservice start
,启动mulservice
服务。这时启动服务失败,查看/var/log/syslog
,提示找不到共享库(这里的mulservice
为自己写的一主多备服务,非系统自带)。
kylin@kylin-X280:~$ mulservice start
Job for mulservice.service failed because the control process exited with error code.
See "systemctl status mulservice.service" and "journalctl -xe" for details.
failed! `这时启动服务失败`
kylin@kylin-X280:~$ mulservice status
● mulservice.service - LSB: mulproc server
Loaded: loaded (/etc/init.d/mulservice; generated)
Active: failed (Result: exit-code) since Thu 2020-04-09 13:16:34 CST; 3min 20s ago
Docs: man:systemd-sysv-generator(8)
Process: 1261 ExecStart=/etc/init.d/mulservice start (code=exited, status=127)
4月 09 13:16:34 kylin-X280 systemd[1]: Starting LSB: mulproc server...
4月 09 13:16:34 kylin-X280 mulservice[1261]: /usr/bin/mulproc: error while lo…ory
4月 09 13:16:34 kylin-X280 systemd[1]: mulservice.service: Control process e…/n/a
4月 09 13:16:34 kylin-X280 systemd[1]: mulservice.service: Failed with resul…de'.
4月 09 13:16:34 kylin-X280 systemd[1]: Failed to start LSB: mulproc server.
tail -f /var/log/syslog
Apr 9 13:15:37 kylin-X280 systemd[1]: Stopping LSB: mulproc server...
Apr 9 13:15:37 kylin-X280 systemd[1]: mulservice.service: Succeeded.
Apr 9 13:15:37 kylin-X280 systemd[1]: Stopped LSB: mulproc server.
Apr 9 13:16:34 kylin-X280 systemd[1]: Starting LSB: mulproc server...
Apr 9 13:16:34 kylin-X280 mulservice[1261]: /usr/bin/mulproc: error while loading shared libraries: libmul.so: cannot open shared object file: No such file or directory `查看日志,还是提示找不到共享库,说明配置的LD_LIBRARY_PATH没有起到作用。`
分析原因:service服务无法使用系统环境变量,会把大部分环境变量去掉
service
运行指定服务(称之为System V初始脚本)时,把大部分环境变量去掉了,只保留TERM
、PATH
、LANG
等少数变量,并且把当前路径置为/,也就是说是在一个可以预测的非常干净的环境中运行服务脚本。这种脚本保存在/etc/init.d
目录中,它至少要支持start和stop命令。
虽然在/etc/environment
或/etc/profile
中配置了LD_LIBRARY_PATH
,但是service把大部分环境变量去掉,包括LD_LIBRARY_PATH
,所以在运行service服务时,是无法根据配置的LD_LIBRARY_PATH
找到共享库的。
解决方法:修改/etc/init.d/服务脚步
,加入环境变量
例如修改/etc/init.d/mulservice
,在脚步中加入export LD_LIBRARY_PATH=/home/kylin/Multiple/lib/
#!/bin/sh
### BEGIN INIT INFO
# Provides: mulservice
# Required-Start: $local_fs $remote_fs $network $syslog $named
# Required-Stop: $local_fs $remote_fs $network $syslog $named
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# X-Interactive: true
# Short-Description: mulproc server
# Description: Start mulproc server
# This script will start the mulproc server.
### END INIT INFO
DESC="mulproc server"
#由于service会去掉大部分的环境变量,在这里加入LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/home/kylin/Multiple/lib/
set -e
. /lib/lsb/init-functions
[ -x /usr/bin/mulproc ] || exit 0
.........................................................
执行mulservice start
,可以正常启动
kylin@kylin-X280:~$ mulservice start
[....] Starting mulservice (via systemctl): mulservice.serviceWarning: The unit file, source configuration file or drop-ins of mulservice.service changed on disk. Run 'systemctl daemon-reload' to reload units.
. ok