Linux类似RPM的SHELL安装包的制作

在linux操作系统中,安装程序rhel系列有rpm,debian系列有deb,很多时候假如想要照顾所有linux系列,仅仅制作rpm是不够的,而且在制作rpm的时候,SPEC的编写是很多人觉得比较蛋疼的事情,所以能否提供一种linux都兼容的安装模式是有必要的,而bash是所有linux都存在的,所以最好的方法是提供一个类shell脚本来实现

其实很多大厂商的产品就是用这种模式,比如可以去VMware官网下载一个Linux操作系统下的虚拟机安装包,你会发现后缀名比较奇葩,.run或者.bud,用编辑器打开就会发现安装包其实是一个复杂的shell脚本

RPM的机制是按照SPEC里规定的内容和过程,通过源代码编译,将SPEC里配置的需要安装的文件集成起来放到一个后缀为.rpm的包里,可以通过rpm -ivh执行这个rpm包将需要安装的可执行程序和配置文件安装到指定的路径下

同理可以将源代码(或者仅仅生成的可执行程序)和一个install的脚本集成到一个shell脚本包里,然后通过这个包,或者说shell脚本的执行就会进行安装,下面是一个简单hello world的例子:

[lihui@81 test_bin]# ls
hello  install.sh

[lihui@81 test_bin]# ls hello/
hello.c

[lihui@81 test_bin]# cat hello/hello.c
#include <stdio.h>

void main(){
    printf(“Hello World!\n”);
}

[lihui@81 test_bin]# cat install.sh
#!/bin/bash

now_dir=`pwd`
tmp_dir=/tmp
module=hello

sed -n -e ‘1,/^exit 0$/!p’ $0 > $tmp_dir/$module.tar.gz 2>/dev/null

tar zxvf $tmp_dir/$module.tar.gz
cd $module
gcc $module.c
cp a.out /usr/local/bin

rm -f $tmp_dir/$module.tar.gz

cd $now_dir
rm -f $module.tar.gz
rm -rf $module

exit 0

 

目录下一个是保存有我们需要编译的hello.c文件的hello目录,另一个脚本install.sh就是可以想成是制作RPM里面的spec文件,记录了如何编译我们的hello.c以及如何安装(将a.out给copy到系统目录),其实这个脚本就sed这行难一点,$0表示当前运行的脚本,1,/^exit 0$/就表示从第一行到以exit开头,0结尾的那行,显示sed要截取的就是本身这个脚本的全部(这句大家都喜欢这么写,可能显得高大上吧,我觉得换种方法更简单),后面的将sed的标准输出重定向到我们源代码压缩后的.tar.gz,然后将标准错误输出输出到/dev/null,很容易理解

下面是具体实现步骤:

1:将需要编译安装的源代码制作一个tar包

[lihui@81 test_bin]# tar zcvf hello.tar.gz hello/
hello/
hello/hello.c

2:制作shell包

[lihui@81 test_bin]# cat install.sh hello.tar.gz > hello.run
[lihui@81 test_bin]# ls
hello  hello.run  hello.tar.gz  install.sh

这样看着就高大上的shell执行软件包hell.run就生成了

3:安装,需要root权限

[root@81 test_bin]# sh hello.run
hello/
hello/hello.c
也可以给hello.run添加可执行a+x权限,然后./hello.run执行

[root@81 test_bin]# whereis a.out
a: /usr/local/bin/a.out

可见的确照我们脚本里写的,copy到了/usr/local/bin下,为了确认正确,执行一下:

[root@81 test_bin]# /usr/local/bin/a.out
Hello World!

重要的一点:

这样实现其实是将源代码也放到了shell包里,然后编译生成可执行程序也在里面,这就比较危险,因为不是纯正的二进制:

[root@iProbe81 packet]# ls
hello.run  install.sh
[root@iProbe81 packet]# sed -n -e ‘1,/^exit 0$/!p’ hello.run > ./hello.tar.gz
[root@iProbe81 packet]# ls
hello.run  hello.tar.gz  install.sh
[root@iProbe81 packet]# tar zxvf hello.tar.gz
hello/
hello/hello.c

可见通过一个sed命令,就把源代码给弄出来了,所以如果交叉编译等都处理好了,可以先都生成可执行程序,然后再install.sh里仅仅是将它们copy到系统目录,这样就不涉及到源代码的问题了,而且想去掉符号表都可以直接进行

发表回复