Ldd 是一個 Linux 命令行實用程序,用於在用戶想知道可執行文件甚至共享庫的共享庫依賴項的情況下。 您可能已經註意到 Linux 機器的 /lib 和 /usr/lib 目錄中有許多以 lib* 開頭的文件。 這些文件稱為庫。 庫是資源的集合,例如子程序/函數、類、值或類型規範。
庫使程序可以使用通用例程,而無需維護其源代碼的管理開銷,或每次編譯程序時編譯它們的處理開銷。
有兩種類型的庫:
靜態庫: 不依賴外部庫運行的完整程序的靜態庫。 靜態鏈接程序的特點是它們無需安裝任何先決條件即可運行。 靜態庫以 *.a
擴展並且這些庫被包含(一個單獨的副本)到需要其功能的程序中。
動態庫: 小程序的動態庫,這些庫以 .so
擴展,當很多程序運行時使用動態鏈接的另一個特點,它可以共享一個庫的一個副本,而不是用許多相同的代碼副本來佔用內存。 所以最近的程序使用動態鏈接。 在本文中,我們將通過命令 ldd
用於管理共享庫。
共享庫
當我們編寫程序時,我們需要很多其他人已經編寫的代碼來為我們執行例行程序或專門的功能。 這些代碼段存儲在共享庫中。 為了使用它們,我們在構建程序或運行程序時將它們與我們的代碼鏈接起來。
LDD 命令語法和選項
ldd 命令打印共享對象依賴項。 命令的語法是:
ldd [OPTION]... FILE...
我們可以使用可以插入的 ldd 命令開關
[OPTION] 在上面的命令中點:
- -v :打印所有信息。
- -d :處理數據重定位。
- -r :處理數據和函數重定位。
- -u :打印未使用的直接依賴項。
在執行命令之前,請記下以下幾點:
– ld-linux.so 文件是動態鏈接器或加載器,它檢查所需程序的所需鏈接或庫緩存並加載它。
– 緩存文件 /etc/ld.so.cache 包含在 /etc/ld.so.conf 中指定的目錄中找到的庫列表。 這有助於提供更快的動態鏈接。
– 文件 /etc/ld.so.conf 指定搜索庫的目錄
1) 顯示命令的依賴關係
我們將顯示 cp 命令的依賴項。
$ ldd /bin/cp
Output:
linux-vdso.so.1 => (0x00007fffaf3ff000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003a06a00000)
librt.so.1 => /lib64/librt.so.1 (0x0000003a06200000)
libacl.so.1 => /lib64/libacl.so.1 (0x0000003a13000000)
libattr.so.1 => /lib64/libattr.so.1 (0x0000003a0ea00000)
libc.so.6 => /lib64/libc.so.6 (0x0000003a05200000)
libdl.so.2 => /lib64/libdl.so.2 (0x0000003a05a00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003a04a00000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003a05600000)
2) 詳細顯示命令的依賴關係
我們將顯示依賴項 cp
使用更多詳細信息的命令 -v
選項。
$ ldd -v /bin/cp
Output:
linux-vdso.so.1 => (0x00007fff473ff000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003a06a00000)
librt.so.1 => /lib64/librt.so.1 (0x0000003a06200000)
libacl.so.1 => /lib64/libacl.so.1 (0x0000003a13000000)
libattr.so.1 => /lib64/libattr.so.1 (0x0000003a0ea00000)
libc.so.6 => /lib64/libc.so.6 (0x0000003a05200000)
libdl.so.2 => /lib64/libdl.so.2 (0x0000003a05a00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003a04a00000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003a05600000)
Version information:
/bin/cp:
librt.so.1 (GLIBC_2.2.5) => /lib64/librt.so.1
libattr.so.1 (ATTR_1.1) => /lib64/libattr.so.1
libacl.so.1 (ACL_1.2) => /lib64/libacl.so.1
libacl.so.1 (ACL_1.0) => /lib64/libacl.so.1
libc.so.6 (GLIBC_2.6) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.4) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.3) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.3.4) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
/lib64/libselinux.so.1:
libdl.so.2 (GLIBC_2.2.5) => /lib64/libdl.so.2
ld-linux-x86-64.so.2 (GLIBC_2.3) => /lib64/ld-linux-x86-64.so.2
libc.so.6 (GLIBC_2.4) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.8) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.3) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.3.4) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
/lib64/librt.so.1:
libpthread.so.0 (GLIBC_2.2.5) => /lib64/libpthread.so.0
libpthread.so.0 (GLIBC_PRIVATE) => /lib64/libpthread.so.0
libc.so.6 (GLIBC_2.3.2) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
libc.so.6 (GLIBC_PRIVATE) => /lib64/libc.so.6
/lib64/libacl.so.1:
libattr.so.1 (ATTR_1.0) => /lib64/libattr.so.1
libc.so.6 (GLIBC_2.4) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.3.4) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
/lib64/libattr.so.1:
libc.so.6 (GLIBC_2.4) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
/lib64/libc.so.6:
ld-linux-x86-64.so.2 (GLIBC_PRIVATE) => /lib64/ld-linux-x86-64.so.2
ld-linux-x86-64.so.2 (GLIBC_2.3) => /lib64/ld-linux-x86-64.so.2
/lib64/libdl.so.2:
ld-linux-x86-64.so.2 (GLIBC_PRIVATE) => /lib64/ld-linux-x86-64.so.2
libc.so.6 (GLIBC_PRIVATE) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
/lib64/libpthread.so.0:
ld-linux-x86-64.so.2 (GLIBC_2.3) => /lib64/ld-linux-x86-64.so.2
ld-linux-x86-64.so.2 (GLIBC_2.2.5) => /lib64/ld-linux-x86-64.so.2
ld-linux-x86-64.so.2 (GLIBC_PRIVATE) => /lib64/ld-linux-x86-64.so.2
libc.so.6 (GLIBC_2.3.2) => /lib64/libc.so.6
libc.so.6 (GLIBC_PRIVATE) => /lib64/libc.so.6
libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
3) 顯示命令未使用的直接依賴
我們可以顯示未使用的直接依賴項 cp
命令使用 -u
選項。
$ ldd -u /bin/cp
Output:
Unused direct dependencies:
/lib64/libselinux.so.1
/lib64/librt.so.1
/lib64/libacl.so.1
/lib64/libattr.so.1
4) 顯示 ldd 僅適用於動態可執行文件
我們將展示 ldd
僅適用於使用動態可執行文件 -r
選項。
$ ldd -r /smart/pycharm-community-2017.3.3/bin/pycharm.sh
Output:
not a dynamic executable
輸出顯示一條明確的消息狀態,表明所提供的文件不是動態可執行文件。
5) ldd 與標準命令行可執行文件
當我們嘗試 ldd
在標準命令行可執行文件上,例如 ls
, 我們需要動態可執行文件的完整路徑。
$ ldd ls
Output:
ldd: ./ls: No such file or directory
我們看到 ldd
說它找不到 ls
.
$ ldd /bin/ls
Output:
linux-vdso.so.1 => (0x00007fff5cbea000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003a06a00000)
librt.so.1 => /lib64/librt.so.1 (0x0000003a06200000)
libcap.so.2 => /lib64/libcap.so.2 (0x0000003a07600000)
libacl.so.1 => /lib64/libacl.so.1 (0x0000003a13000000)
libc.so.6 => /lib64/libc.so.6 (0x0000003a05200000)
libdl.so.2 => /lib64/libdl.so.2 (0x0000003a05a00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003a04a00000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003a05600000)
libattr.so.1 => /lib64/libattr.so.1 (0x0000003a0ea00000)
但是使用絕對路徑, ldd
工作正常。
6) 知道一個給定的可執行守護進程支持 TCP Wrapper
要確定給定的可執行守護程序是否支持 TCP Wrapper,請運行以下命令。
$ sudo ldd /usr/sbin/sshd | grep libwrap
Output:
libwrap.so.0 => /lib64/libwrap.so.0 (0x00007f1cc2ac6000)
輸出表明 OpenSSH (sshd) 守護程序支持 TCP Wrapper。
7) ldd 缺少依賴項
我們可以使用 ldd
當可執行文件由於缺少依賴項而失敗時的命令。 一旦我們發現缺少的依賴項,我們就可以安裝它或使用以下命令更新緩存 ldconfig
命令。
$ sudo ldd /bin/mv
libacl.so.1 => /lib/libacl.so.1 (0×40016000)
libc.so.6 => /lib/libc.so.6 (0x4001c000)
libattr.so.1 => /lib/libattr.so.1 (0×40141000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0×40000000)
我們將通過鍵入以下命令執行重定位並報告任何丟失的對象(僅限 ELF)。
$ sudo ldd -d path/to/executable_file
我們將對數據對象和函數執行重定位,並通過鍵入以下命令報告任何丟失的對像或函數(僅限 ELF)。
$ sudo ldd -r path/to/executable_file
常見共享庫相關錯誤
1) 缺少庫錯誤
即使提到的庫在新安裝路徑“/opt/newinstall/lib”中可用,您也可能會遇到缺少庫錯誤。 這是因為系統不知道要檢查庫的目錄。 這可以通過兩種方式中的任何一種來解決。
一個。 執行以下命令,
$ ldconfig -n /opt/newinstall/lib
灣您可以在 /etc/ld.so.conf 文件中看到以下包含行:
包括 ld.so.conf.d/*.conf
因此,在 /etc/ld.so.sonf.d 文件夾中創建一個文件,使用以下內容說 newinstall.conf。
/opt/newinstall/lib
然後,執行:
$ ldconfig
2) 動態鏈接器錯誤,無法映射緩存文件
這可能是由於緩存文件損壞所致。 這可以通過使用 ldconfig 重建緩存文件來解決。
$ ldconfig
ldconfig 命令
ldconfig 創建必要的鏈接和緩存(供運行時鏈接器 ld.so 使用)到在命令行指定的目錄中找到的最新共享庫,在文件 /etc/ld.so.conf 和在受信任的目錄(/usr/lib 和 /lib)中。
舉些例子:
執行以下命令為共享二進製文件設置正確的鏈接並重建緩存。
$ ldconfig –v
安裝新共享庫後執行以下命令將正確更新/lib中的共享庫符號鏈接。
$ ldconfig -n /lib
以下命令將打印當前緩存。
$ ldconfig -p
結論
在本教程中,我們學習瞭如何使用 ldd 命令以及如何在 linux 命令行中使用。 希望您喜歡閱讀本教程,如果您有任何建議,請提出建議。
另請閱讀:
- 8 Linux Tee 命令與示例
- 如何通過示例使用 Linux Tr 命令