2009-01-20 76 views
4

我認爲這個問題對於shell腳本怪物來說相當容易。Bash腳本創建符號鏈接到共享庫

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

我需要的是開始了與共享庫文件,如「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」。

只有ldconfig -nN的解決方案可以工作,如果有Java部分的解決方法。

回答

5
for baselib in "[email protected]" 
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 "[email protected]" 
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 "[email protected]" 
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的內容。經修改,腳本生成以下輸出。刪除回聲讓它執行鏈接命令。

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腳本一個有趣的和經常被忽視的一點:在一段時間的條件塊操作的順序不一定是單一的命令。具有編輯操作的行的狀態不會影響整個測試是否成功;最後一個命令的退出狀態'[ -n "$extn" ]'控制循環是否繼續。

+0

它不起作用:-(但是謝謝你的試用 – 2009-01-21 14:08:25

11

我相信ldconfig是這樣做的標準工具。

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

編輯是的,如果你運行

ldconfig -v 

你會看到它產生基於圖書館內部的所有鏈接。

ldconfig /path/to/dir 

將僅在該目錄創建文件的鏈接

的說明雖然,我打它,它似乎並不一致創造。所以$,剛剛的.so。{}大

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

 
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]

這是黑客代碼和更換」 0.1" 用空格之後。

ldconfig生成「libmagic」。所以「(是的,包含空格)

+2

「LDCONFIG -nN。」只適用於當前目錄,但它只創建主要版本的庫(libmylib.1 - > libmylib.1.10)。 – 2009-01-20 21:55:22

3

從喬納森·萊弗勒腳本導出(我已經添加了這是一個在我的〜/ 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