/etc/profile中配置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.solibmul.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/mulprocsudo 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,使用sudosusu root都是不會執行/etc/profile,找不到LD_LIBRARY_PATH
  • 使用susu 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/mulprocsudo 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初始腳本)時,把大部分環境變量去掉了,只保留TERMPATHLANG等少數變量,並且把當前路徑置爲/,也就是說是在一個可以預測的非常乾淨的環境中運行服務腳本。這種腳本保存在/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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章