Bash脚本用于创建指向共享库的符号链接

时间:2009-01-20 16:46:41

标签: linux bash scripting java-native-interface 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”。

只有ldconfig -nN的解决方案才有效,如果有一个Java部件的解决方法。

3 个答案:

答案 0 :(得分:13)

我相信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”(是的,包括空格)

答案 1 :(得分:6)

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脚本的一个有趣且经常被忽视的观点:一段时间条件块中的操作序列不必是单个命令。具有编辑操作的行的状态不会影响整个测试是否成功;最后一个命令的退出状态“[ -n "$extn" ]”控制循环是否继续。

答案 2 :(得分:3)

来自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