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

Linux Bash脚本创建指向共享库的符号链接,linux,bash,scripting,java-native-interface,shared-libraries,Linux,Bash,Scripting,Java Native Interface,Shared Libraries,我认为这个问题对你来说相当简单 我正在寻找通过bashshell脚本创建指向Unix共享库的符号链接的最优雅、最短的方法 我需要的是从共享库文件列表开始,例如“libmythings.so.1.1,libotherthings.so.5.11”,创建符号链接,例如: libmythings.so -> libmythings.so.1 -> libmythings.so.1.1 libotherthings.so -> libotherthings.so.5 -> lib

我认为这个问题对你来说相当简单

我正在寻找通过bashshell脚本创建指向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$,just.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) lib#rm libmagic.so lib#rm libmagic.so.1 lib#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”(是,包含空格)

我作弊了-所有链接都指向基本库(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”的脚本)


“ldconfig-nN.”对于当前目录非常有效,但它只创建库的主要版本(libmylib.1->libmylib.1.10)。您得到了正确的答案,尽管我已经通过“cut”命令自己完成了。谢谢
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
#!/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