LD_LIBRARY_PATH配置不生效
- LIBRARY_PATH與LD_LIBRARY_PATH
- 問題復現
- 分析1:是否執行`source /etc/profile`
- 分析2:`LD_LIBRARY_PATH`中配置的目錄是否正確
- 分析3:`LD_LIBRARY_PATH`中配置的目錄,裏面的動態庫是否創建了軟連接,若共享庫沒有創建軟連接,也會找不到。
- 分析4:用戶登錄才執行`/etc/profile`(直接運行程序可以,`sudo`運行程序找不到共享庫)
- 查看現象:`ldd -d /usr/bin/mulproc `與`sudo ldd -d /usr/bin/mulproc `
- 分析原因:`/etc/profile`的執行過程
- 解決方法:將`LD_LIBRARY_PATH`放入`/etc/environment`文件中
- 分析5:`Linux service`無法使用系統環境變量問題
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