在Linux環境執行程序時經常會遇到提示程序依賴動態庫.so文件不存在的情況,出現報錯"error while loading shared libraries: XXXX.so.XX: cannot open shared object file: No such file or directory"信息。遇到這種問題如何解決?本文主要講述如下內容:
(1)ldd命令的語法和使用方法。如果出現動態庫報錯通常都是用這個命令執行查看一下。
(2)rpm命令使用。包括rpm命令查詢、安裝、卸載相關rpm軟件包。
(3)ldconfig命令和相關環境變量。
(4)動態庫缺失問題解決的過程。
1、ldd 打印可執行程序依賴動態庫列表
(1)ldd基礎語法
(2)ldd使用實例
主要就是ldd + 可執行程序名或者ldd `which 程序名`,如ldd `which cp`。如果是全部查看當前目錄下文件。可以使用ldd *
說明:“=>”左邊表示該程序需要連接的共享庫.so 名稱,右邊表示從共享庫.so在Linux文件系統中的具體位置。默認情況下,/etc/ld.so.conf 文件中包含有默認的共享庫搜索路徑。
2、ldconfig 動態鏈接庫管理命令
ldconfig主要作用是在默認搜尋目錄(/lib和/usr/lib)以及動態庫配置文件/etc/ld.so.conf內所列的目錄下,搜索出可共享的動態鏈接庫,從而創建出動態裝入程序(ld.so)所需的連接和緩存文件,緩存文件默認為 /etc/ld.so.cache。
(1)ldconfig基本語法
ldconfig [-v|--verbose] [-p|--print-cache] [-?|--help|--usage] path...
選項說明:
-v或--verbose : 顯示正在掃描的目錄及搜索到的動態鏈接庫,還有它所創建的連接的名字;
-p或--print-cache : 打印出當前緩存文件所保存的所有共享庫的名字;
(2)lddconfig使用方法
a、直接執行 lddconfig。用於在/etc/ld.so.conf新增一行待寫入高速緩存當中的動態函數庫。
b、lddconfig -p。列出目前的所有函數庫數據內容(/etc/ld.so.cache)
3、rpm軟件包管理命令
rpm(RedHat Package Manager)用於安裝、更新、卸載系統軟件。rpm基本使用場景如下:
(1)rpm安裝
rpm -ivh package_name 正常安裝,如果缺少依賴文件時會安裝失敗
rpm -ivh --nodeps --force package_name 強制安裝,即使缺少依賴文件。通常情況下不建議強制安裝,因為可能安裝后無法運行。
(2)rpm升級或更新軟件
rpm -Uvh/Fvh package_name 升級或更新軟件
-Uvh 后面接的軟件即使沒有安裝過,則系統將予以直接安裝; 若后面接的軟件有安裝過舊版,則系統更新至新版;
-Fvh 如果后面接的軟件幵未安裝,則該軟件不會被安裝;若后面接的軟件有安裝過舊版,則系統更新至新版。
(3)rpm查詢軟件包
重點再說一下本文描述中會用到的-qf/-qi參數。目的是期望通過這兩個參數去獲取缺失動態庫可以通過安裝哪一個軟件可以獲取。
rpm -qi 動態庫名稱。根據輸出結果中的Source RPM可以獲取安裝的軟件名稱
[root@www ~]# rpm -qi logrotate
Name : logrotate Relocations: (not relocatable) Version : 3.7.4 Vendor: CentOS Release : 8 Build Date: Sun 02 Dec 2007 08:38:06 AM CST Install Date: Sat 09 May 2009 11:59:05 PM CST Build Host: builder6 Group : System Environment/Base Source RPM: logrotate-3.7.4-8.src.rpm
rpm -qf 動態庫 輸出安裝的軟件名稱
[root@www ~]# rpm -qf /bin/sh
bash-3.2-21.el5 --> 說明sh文件是通過安裝bash-3.2-21.el5獲取。
(4)rpm卸載軟件包
rpm -e package_name 卸載軟件包。
rpm -e package_name --nodeps --force 強制卸載軟件包。
4、cannot open shared object file解決步驟
這里描述一下分析思路。因為沒有linux服務器,所以描述中的例子是自己構造的。但不影響理解。
(1)在服務器A上執行程序執行ldd 可執行程序。輸出結果如下
linux-vdso.so.1 => (0x00007fff48ff0000)
libcrypt.so.1 => /lib64/libcrypt.so.1 (0×0000003065800000)
libpcre.so.1 => not found
libssl.so.6 => /lib64/libssl.so.6 (0×0000003067000000)
libcrypto.so.6 => /lib64/libcrypto.so.6 (0×0000003066400000)
libdl.so.2 => /lib64/libdl.so.2 (0×0000003063000000)
(2)在正常可以執行該程序的服務器B上,執行ldd 可執行程序。顯示如下:
linux-vdso.so.1 => (0x00007fff48ff0000)
libcrypt.so.1 => /lib64/libcrypt.so.1 (0×0000003065800000)
libpcre.so.1 => /lib64/libpcre.so.1
libssl.so.6 => /lib64/libssl.so.6 (0×0000003067000000)
libcrypto.so.6 => /lib64/libcrypto.so.6 (0×0000003066400000)
libdl.so.2 => /lib64/libdl.so.2 (0×0000003063000000)
從這里,我們可以知道服務器A上/lib64目錄下由於缺少libpcre.so.1文件導致程序執行報錯提示缺少動態庫。下一步就是開始想辦法安裝libpcre.so.1文件。這里有三種解決方法供參考,一種是安裝libpcre.so.1對應的軟件,一種是獲取libpcre.so.1庫文件並放置在 /lib64目錄下。最后一種是獲取libpcre.so.1庫文件庫文件並上傳至服務器A任意目錄下上並設置LD_LIBRARY_PATH變量
方法一:獲取軟件並設置LD_LIBRARY_PATH變量方法。如下:
Step1:從服務器B上下載libpcre.so.1對應軟件,上傳至服務器A上任意目錄下。如/opt。
Step2:設置LD_LIBRARY_PATH變量。執行export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt。說明:LD_LIBRARY_PATH是Linux環境變量名,該環境變量主要用於指定查找共享庫(動態鏈接庫)時除了默認路徑之外的其他路徑。
Step3:重新執行程序,問題解決。
方法二:獲取軟件並放置指定目錄下。如下:
Step1:從服務器B上下載libpcre.so.1對應軟件,上傳至服務器A上的/lib64目錄下。/lib64為步驟(2)中查出缺失文件的目錄。
Step2:重新執行程序,問題解決。
方法三:安裝libpcre.so.1對應的軟件方法如下:
Step1:在服務器B上執行rpm -qf /lib64/libpcre.so.1。
[root@www ~]# rpm -qf /lib64/libpcre.so.1 libpcre-3.2-21.el5 --> 說明libpcre.so.1文件是通過安裝libpcre-3.2-21.el5獲取。
Step2:查看Linux服務器系統版本,獲取對應的鏡像包,從而獲取libpcre-3.2-21.el5.rpm安裝軟件
Step3:執行rpm -ivh libpcre-3.2-21.el5.rpm安裝。
Step4:重新執行程序,問題解決。