2009-01-20 75 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