我们在使用类 Unix 系统时,经常会用到一些以“.bin”或者“.run”结尾的安装程序 (Installer)。(为描述方便,这里我们使用“Bin 安装程序”来泛指这种安装程序。)Bin 安装程序不依赖于系统发行版自己的包 (package) 管理器来实现应用程序的安装和卸载,而是完全自己控制安装的整个过程,程序卸载的时候需要用户执行应用程序安装目录下的卸载脚本来完成。
Bin 安装程序最大的好处就是可以运行在多种类 Unix 平台,以及基于相同核心的多个发行版上,而不需要关心">系统使用何种包管理器。在一定程度上实现了跨平台。
但是,非常遗憾的是,这种安装程序不能用在 Windows 平台上。Windows 平台上的安装程序需要特别的制作。这个是由 Bin 安装程序本身使用类 Unix 平台通用的 Shell 脚本来实现整个安装过程的引导和控制造成的。
好消息是,现在11545.html">我们有了一种强大的,可以同时运行在类 Unix 平台和 Windows 平台的脚本 -Python。随着 Python 的普及,越来越多的系统整合开始基于 Python 来完成,使得现在很大一部分类 Unix 平台都默认部署了 Python 的运行环境。即使没有默认安装,用户在安装其它应用的时候可能也都安装了 Python。
所以,我们能不能使用 Python 来实现一个可以在类 Unix 平台和 Windows 平台都通用的安装程序呢?这个安装程序又如何来实现呢?本文将和大家探讨这个问题,并提供一个解决这个问题的思路。本文抛开被安装程序的跨平台能力,仅讨论安装程序本身的跨平台特性和实现方法。
本文首先分析了 Bin 安装程序的结构和工作原理 , 然后介绍如何应用 Python 实现类似功能 , 并对 Python 实现的局限性以及可能的解决方案进行了探讨。
Bin 安装程序的执行过程
Bin 安装程序在运行的最初阶段会提供一些向导界面 , 向用户提供关于被安装产品的相关信息 , 并引导用户输入安装程序需要的配置信息 . 安装程序获取了需要的配置信息后 , 进入具体的安装阶段。
在安装阶段 , Bin 安装程序首先展开一些包,这些包中包含一些安装程序自身所依赖的库和安装程序的配置信息,以及将要安装的用户应用程序。
事实上,这些包被展开的过程分为两个阶段。在第一个阶段,安装程序将这些包的压缩文件从安装程序自身中分离出来,生成单独的压缩文件。然后在第二阶段,使用解压缩工具将这些压缩文件解压,并设置需要的系统环境变量。最基本的是 PATH 和 JAVA_HOME 这两个变量。
在这之后,安装程序读取安装配置,取得用户自定义的安装脚本(pre-install, post-install),按照既定的顺序执行它们。
最后,安装程序将安装过程中记录下来的被安装的文件列表和卸载程序模板,以及用户自定义的卸载脚本(pre-uninstall, post-uninstall)合并,生成卸载程序,并放入用户应用程序的安装目录。
Bin 安装程序的实现分析
那么,Bin 安装程序是如何实现这整个过程的控制的,安装程序文件本身又是一个什么样的结构呢?我们接下来进行分析。
Bin 安装程序本身其实是一个包含二进制数据的 Shell 脚本。简单的安装程序可以由一段脚本代码加上一个压缩包的二进制数据构成。复杂的可能会包含多段二进制数据。
文件的基本结构如下图
图示 1:Bin 文件结构示意图
知道了文件结构之后,我们就要看看安装程序是怎么将自身文件内部的二进制数据分离出来了。其实这个有很多种方法实现。最基本的方法可以使用 tail 命令,或者使用 sed 命令。复杂些的可以使用读取文件的方法。