簡體   English   中英

用於創建指向共享庫的符號鏈接的 Bash 腳本

[英]Bash script to create symbolic links to shared libraries

我認為這個問題對你的 shell 腳本怪物來說相當容易。

我正在尋找通過 bash shell 腳本創建指向 Unix 共享庫的符號鏈接的最優雅和最短的方法。

我需要的是從共享庫文件列表開始,例如“libmythings.so.1.1,libotherthings.so.5.11”,獲取創建的符號鏈接,例如:

libmythings.so -> libmythings.so.1 -> libmythings.so.1.1
libotherthings.so -> libotherthings.so.5 -> libotherthings.so.5.11

庫文件位於包含其他文件(例如其他 shell 腳本)的目錄中。

編輯:嗯,“ldconfig -nN”。 可以正常工作,但我還需要在“.so”之后沒有附加庫主要編號的鏈接,至少是其中一個庫,因為一個或多個庫是來自 Java 的 JNI 調用的入口點,所以當一個庫通過 System.loadlibrary("libraryname") 實例化它需要一個名為“libraryname.so”的庫,而不是“libraryname.so.X”。

如果 Java 部分有解決方法,那么僅使用 ldconfig -nN 的解決方案就可以工作。

我相信ldconfig是執行此操作的標准工具。

我記得在某個地方它可以根據內部版本信息生成符號鏈接,但現在找不到來源。

編輯是的,如果你跑

ldconfig -v 

您將看到它根據庫內部結構生成所有鏈接。

ldconfig /path/to/dir 

只會為該目錄中的文件創建鏈接

不過請注意,我玩過它,它似乎並沒有始終如一地創建 .so$,只是 .so.{major}

我不確定它的內部是如何工作的,但我知道:

lib # rm libmagic.so
lib # rm libmagic.so.1
lib # ldconfig 
lib # file libmagic.so.1   
libmagic.so.1: symbolic link to `libmagic.so.1.0.0'
lib # file libmagic.so 
libmagic.so: cannot open `libmagic.so' (No such file or directory)

所以是什么決定了它是如何工作的對我來說是個謎

進一步討論后編輯,.la 文件對行為沒有影響。

“SO”名稱字段指示符號鏈接將被稱為什么。

而且只會有一個。

0x000000000000000e(SONAME)庫soname:[libmagix.so]

這是在破解代碼並用空格替換“.1”之后。

ldconfig 生成“libmagic.so”(是的,包括空格)

for baselib in "$@"
do
     shortlib=$baselib
     while extn=$(echo $shortlib | sed 's/\.[0-9][0-9]*$//')
           [ -n "$extn" ]
     do
         shortlib=$(basename $shortlib $extn)
         ln -s $baselib $shortlib
     done
done

我作弊了 - 所有鏈接都指向基礎庫(libmythings.so.1.1); 如果你真的想鏈接,那么你需要:

for baselib in "$@"
do
     shortlib=$baselib
     while extn=$(echo $shortlib | sed 's/\.[0-9][0-9]*$//')
           [ -n "$extn" ]
     do
         shorterlib=$(basename $shortlib $extn)
         ln -s $shortlib $shorterlib
         shortlib=$shorterlib
     done
done           

當心 - 未經測試的代碼。


傲慢先於宿敵。

評論到達,上面的代碼不起作用 - 評論是正確的。 帶有原位測試的固定版本是:

set -- libname.so.5.1.1

for baselib in "$@"
do
    shortlib=$baselib
    while extn=$(echo $shortlib | sed -n '/\.[0-9][0-9]*$/s/.*\(\.[0-9][0-9]*\)$/\1/p')
          [ -n "$extn" ]
    do
        shortlib=$(basename $shortlib $extn)
        echo ln -s $baselib $shortlib
    done
done

更改在sed命令中。 此版本默認不打印任何內容 ( -n ),僅匹配以點結尾的行,后跟數字,然后刪除除該后綴之外的所有內容,並打印剩余的內容以分配給 extn。 修改后,腳本生成以下輸出。 刪除 echo 以使其執行鏈接命令。

ln -s libname.so.5.1.1 libname.so.5.1
ln -s libname.so.5.1.1 libname.so.5
ln -s libname.so.5.1.1 libname.so

該腳本說明了有關 shell 腳本的一個有趣但經常被忽視的點:while 條件塊中的操作序列不必是單個命令。 編輯操作所在行的狀態不影響測試整體是否成功; 最后一個命令的退出狀態,' [ -n "$extn" ] ',控制循環是否繼續。

源自 Jonathan Leffler 的腳本(我在 ~/bin 中將其添加為名為“liblinks”的腳本)

#!/bin/bash
# liblinks - generate symbolic links 
# given libx.so.0.0.0 this would generate links for libx.so.0.0, libx.so.0, libx.so
#

# By adding sudo to the ls command, we get permission to do the linking (or get an empty list)
LIBFILES=`sudo ls lib*.so.*`
for FILE in $LIBFILES;
   do
   echo $FILE
    shortlib=$FILE
    basename=$FILE
    while extn=$(echo $shortlib | sed -n '/\.[0-9][0-9]*$/s/.*\(\.[0-9][0-9]*\)$/\1/p')
          [ -n "$extn" ]
    do
        shortlib=$(basename $shortlib $extn)
        sudo ln -fs $basename $shortlib
        basename=$shortlib
    done

   done

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM