7

我认为这个问题对于你的 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 的解决方案就可以工作。

4

3 回答 3

14

我相信ldconfig这是执行此操作的标准工具。

我记得在某个地方它可以根据内部版本信息生成符号链接,但现在找不到源。

编辑是的,如果你运行

ldconfig -v 

您将看到它根据库内部生成所有链接。

ldconfig /path/to/dir 

只会为该目录中的文件创建链接

不过需要注意的是,我玩过它,它似乎并没有始终如一地创建 .so$,只是 .so.{major}

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

lib # rm libmagic.so
库#rm libmagic.so.1
库#ldconfig
lib # 文件 libmagic.so.1   
libmagic.so.1:指向“libmagic.so.1.0.0”的符号链接
lib # 文件 libmagic.so
libmagic.so:无法打开“libmagic.so”(没有这样的文件或目录)

所以是什么决定了它是如何工作的,对我来说是个谜

进一步区分后编辑,.la 文件对行为没有影响。

“SO”名称字段指示符号链接将被调用。

而且只会有一个。

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

这是在破解代码并将“.1”替换为空格之后。

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

于 2009-01-20T16:56:48.443 回答
7
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(修改后,脚本生成以下输出。删除 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" ]控制循环是否继续。

于 2009-01-20T16:58:40.157 回答
5

源自 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
于 2011-11-15T23:30:51.897 回答