利用ldd打造Linux下的绿色软件包

【原文:http://www.kongch.com/2010/06/ldd-linux-green-software/

题记:其实这个想法来源于一个同事在之前公司的经验,感觉不错,记下来以免忘记。在云泛滥的今天,如何在云上快速部署应用其实是一个很有意思的话题。这种方法在我看来除了安装包比较大坨这一缺点之外,非常适合用来部署云应用。

众所周知绿色软件是windows下的一个概念,指的是仅仅一个文件夹硬copy过来就可以运行的软件,卸载时也同理:删除这个文件夹即可。说白了就是不会向系统文件夹、注册表这些地方乱丢东西的软件。

Linux下安装软件通常是编译安装,不同发行版本也有自己的二进制安装包,例如RedHat的rpm、Ubuntu的deb等。安装的最终结果往往也是向/usr/bin, /usr/lib, /usr/sbin…等诸如此类的文件夹下放上自己需要的东东。二进制包安装的话,卸载起来倒是不麻烦,但如果你是编译安装,而想卸载时又搞丢了当时的Makefile文件,那就比较讨厌了。有方法可以制作类似于Winodws下的绿色软件包吗?

答案是肯定的。我们可以利用ldd来实现这样的功能。ldd会告诉我们对应二进制可执行程序所用到的共享库文件,我们要做的第一步是在已安装好完整应用的机器上把这些共享库文件拿到。第二步便可以在其他干净的机器上利用LD_LIBRARY_PATH指定运行软件时的动态库文件地址,运行对应的二进制程序。

这里我写了一个实现第一步的脚本:

1 #!/bin/sh
2  
3 if [ $# -ne 1 ]; then
4         echo "You should specify a dynamically executable file"
5         exit 1
6 fi
7  
8 if [ ! -x $1 ]; then
9         echo "You should specify a executable file"
10         exit 1;
11 fi
12  
13 path=$1
14  
15 ############# check file type #############
16 result=$(ldd $path)
17  
18 filter=$(file $path|grep dynamically|grep executable)
19  
20 if [ -z "$filter" ]; then
21         echo "$path is not a dynamically executable file!"
22         file $path
23         exit 1
24 fi
25  
26 ########### mkdir for .so files ############
27 packagename=$(basename $path)-pack
28 mkdir -p $packagename
29  
30 IFS="
31 "
32  
33 ######### copy .so files ############
34 for line in $result; do
35         sofile=notexitsfile
36         if [ -z "$(echo $line | grep =)" ]; then
37                 sofile=$(echo $line | awk '{print $1}')
38         else
39                 # has soft link
40                 sofile=$(echo $line | awk '{print $3}')
41         fi
42  
43         if [ ! -f $sofile ]; then
44                 echo "ERROR FILE: $sofile"
45         else
46                 echo "copying $sofile now..."
47                 cp $sofile $packagename
48         fi
49 done
50  
51 cp $path $packagename
52  
53 echo DONE

这个脚本的接收二进制可执行程序的路径作为参数,利用ldd找到对应的so位置,并将它们连同二进制可执行程序本身拷贝到一个文件夹中。脚本正确执行完毕后,这个文件夹就可以拿到其他的干净的机器上运行了。

举个在CentOS5.3上的例子吧,例如我在A机器上已经编译安装(或者rpm 安装)好了ffmpeg。于是乎我就可以执行我的脚本fetchsofiles.sh,以/usr/bin/ffmpeg作为参数:

1 [root@CT53-64-BASE ~]# ./fetchsofiles.sh /usr/bin/ffmpeg
2 copying /usr/lib64/libpostproc.so.51 now...
3 copying /usr/lib64/libswscale.so.0 now...
4 copying /usr/lib/libavdevice.so.52 now...
5 copying /usr/lib/libavformat.so.52 now...
6 copying /usr/lib/libavcodec.so.52 now...
7 copying /usr/lib/libavutil.so.49 now...
8 copying /lib64/libm.so.6 now...
9 copying /lib64/libpthread.so.0 now...
10 copying /lib64/libc.so.6 now...
11 copying /usr/lib64/libz.so.1 now...
12 copying /lib64/libdl.so.2 now...
13 copying /lib64/ld-linux-x86-64.so.2 now...
14 DONE

看来是正确执行了,现在当前目录的ffmpeg-pack下就有了:

1 [root@CT53-64-BASE ~]# ls -lh ffmpeg-pack/
2 total 24M
3 -rwx------ 1 root root  85K Jun  7 05:52 ffmpeg
4 -rwx------ 1 root root 137K Jun  7 05:52 ld-linux-x86-64.so.2
5 -rwx------ 1 root root 506K May 19 09:17 libamrnb.so.3
6 -rwx------ 1 root root 392K May 19 09:17 libamrwb.so.3
7 -rwx------ 1 root root 887K May 19 09:17 libasound.so.2
8 -rwx------ 1 root root 4.5M Jun  7 05:52 libavcodec.so.52
9 -rwx------ 1 root root  25K Jun  7 05:52 libavdevice.so.52
10 -rwx------ 1 root root 647K Jun  7 05:52 libavformat.so.52
11 -rwx------ 1 root root  45K Jun  7 05:52 libavutil.so.49
12 -rwx------ 1 root root  67K May 19 09:17 libbz2.so.1
13 -rwx------ 1 root root 1.7M Jun  7 05:52 libc.so.6<strong></strong>
14 -rwx------ 1 root root 3.2M May 19 09:17 libdirac_decoder.so.0
15 -rwx------ 1 root root 4.5M May 19 09:17 libdirac_encoder.so.0
16 -rwx------ 1 root root  23K Jun  7 05:52 libdl.so.2
17 -rwx------ 1 root root 232K May 19 09:17 libfaac.so.0
18 -rwx------ 1 root root 729K May 19 09:17 libfaad.so.2
19 -rwx------ 1 root root  58K May 19 09:17 libgcc_s.so.1
20 -rwx------ 1 root root 955K May 19 09:17 libmp3lame.so.0
21 -rwx------ 1 root root 601K Jun  7 05:52 libm.so.6
22 -rwx------ 1 root root  22K May 19 09:17 libogg.so.0
23 -rwx------ 1 root root  51K Jun  7 05:52 libpostproc.so.51
24 -rwx------ 1 root root 143K Jun  7 05:52 libpthread.so.0
25 -rwx------ 1 root root  53K May 19 09:17 librt.so.1
26 -rwx------ 1 root root 954K May 19 09:17 libstdc++.so.6
27 -rwx------ 1 root root 161K Jun  7 05:52 libswscale.so.0
28 -rwx------ 1 root root 208K May 19 09:17 libtheora.so.0
29 -rwx------ 1 root root 1.1M May 19 09:17 libX11.so.6
30 -rwx------ 1 root root 1.8M May 19 09:17 libx264.so.68
31 -rwx------ 1 root root  12K May 19 09:17 libXau.so.6
32 -rwx------ 1 root root  22K May 19 09:17 libXdmcp.so.6
33 -rwx------ 1 root root  71K May 19 09:17 libXext.so.6
34 -rwx------ 1 root root  84K Jun  7 05:52 libz.so.1

24M,确实不小。我们现在就可以把这个24M的文件夹随处(*注1)拷贝了,例如我们现在将其拷贝到从来没有安装过ffmpeg及其相关依赖的机器B上,运行LD_LIBRARY_PATH=/your_pack_path /your_pack_path/ffmpeg:

1 [root@CT53-64-BASE ~]# cd ffmpeg-pack/
2 [root@CT53-64-BASE ffmpeg-pack]# LD_LIBRARY_PATH=. ./ffmpeg
3 FFmpeg version 0.5, Copyright (c) 2000-2009 Fabrice Bellard, et al.
4   configuration: --prefix=/usr --libdir=/usr/lib64 --shlibdir=/usr/lib64 --mandir=/usr/share/man --incdir=/usr/include --extra-cflags=-fPIC --enable-libamr-nb --enable-libamr-wb --enable-libdirac --enable-libfaac --enable-libfaad --enable-libmp3lame --enable-libtheora --enable-libx264 --enable-gpl --enable-nonfree --enable-postproc --enable-pthreads --enable-shared --enable-swscale --enable-x11grab
5   libavutil     49.15. 0 / 49.15. 0
6   libavcodec    52.20. 0 / 52.20. 1
7   libavformat   52.31. 0 / 52.31. 0
8   libavdevice   52. 1. 0 / 52. 1. 0
9   libswscale     0. 7. 1 /  0. 7. 1
10   libpostproc   51. 2. 0 / 51. 2. 0
11   built on Nov  6 2009 19:11:04, gcc: 4.1.2 20080704 (Red Hat 4.1.2-46)
12 At least one output file must be specified

很幸运,运行成功了!

  • 注1:所谓随处,并非任意的随处。必须是相同架构(arch),相同内核版本的机器之间才行。因为注意到这些被拷贝的so有的是架构相关,有的直接就是内核自己的so。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值