我们提过以 Tarball 方式释出的软件是需要重新编译可运行的binary program 的。而 Tarball 是以 tar 这个命令来打包与压缩的文件,所以啦,当然就需要先将Tarball 解压缩,然后到原始码所在的目录下进行 makefile 的创建,再以 make来进行编译与安装的动作啊!所以整个安装的基础动作大多是这样的:
注意到上面的第二个步骤,通常在每个软件在释出的时候,都会附上 INSTALL 或者是 README 这种档名的说明档,这些说明档请『确实详细的』阅读过一遍,通常这些文件会记录这个软件的安装要求、软件的工作项目、与软件的安装参数配置及技巧等,只要仔细的读完这些文件,基本上,要安装好tarball 的文件,都不会有什么大问题罗。
至於 makefile 在制作出来之后,里头会有相当多的标的 (target),最常见的就是 install 与 clean 罗!通常『make clean』代表著将目标档 (object file) 清除掉,『make』则是将原始码进行编译而已。注意喔!编译完成的可运行档与相关的配置档还在原始码所在的目录当中喔!因此,最后要进行『makeinstall』来将编译完成的所有咚咚都给他安装到正确的路径去,这样就可以使用该软件啦!
OK!我们底下约略提一下大部分的 tarball 软件之安装的命令下达方式:
请注意,上面的步骤是一步一步来进行的,而其中只要一个步骤无法成功,那么后续的步骤就完全没有办法进行的!因此,要确定每一的步骤都是成功的才可以!举个例子来说,万一今天你在 ./configure 就不成功了,那么就表示 Makefile无法被创建起来,要知道,后面的步骤都是根据 Makefile 来进行的,既然无法创建 Makefile,后续的步骤当然无法成功罗!
另外,如果在 make 无法成功的话,那就表示原始文件无法被编译成可运行档,那么 make install主要是将编译完成的文件给他放置到文件系统中的,既然都没有可用的运行档了,怎么进行安装?所以罗,要每一个步骤都正确无误才能往下继续做!此外,如果安装成功,并且是安装在独立的一个目录中,例如 /usr/local/packages 这个目录中好了,那么你就必需手动的将这个软件的man page 给他写入 /etc/man.config 里面去。
或许你已经发现了也说不定,那就是为什么前一个小节里面,Tarball 要在 /usr/local/src 里面解压缩呢?基本上,在默认的情况下,原本的Linux distribution 释出安装的软件大多是在 /usr 里面的,而使用者自行安装的软件则建议放置在/usr/local 里面。这是考量到管理使用者所安装软件的便利性。
怎么说呢?我们晓得几乎每个软件都会提供线上说明的服务,那就是info 与 man 的功能。在默认的情况下, man 会去搜寻 /usr/local/man 里面的说明文件,因此,如果我们将软件安装在 /usr/local 底下的话,那么自然安装完成之后,该软件的说明文件就可以被找到了。此外,如果你所管理的主机其实是由多人共同管理的,或者是如同学校里面,一部主机是由学生管理的,但是学生总会毕业吧?所以需要进行交接,如果大家都将软件安装在/usr/local 底下,那么管理上不就显的特别的容易吗!
所以罗,通常我们会建议大家将自己安装的软件放置在 /usr/local 下,至於原始码(Tarball)则建议放置在 /usr/local/src (src 为 source 的缩写)底下啊。
再来,让我们先来看一看 Linux distribution 默认的安装软件的路径会用到哪些?我们以apache 这个软件来说明的话 (apache 是 WWW 服务器软件,详细的数据请参考服务器架设篇。你的系统不见得有装这个软件):
我们会发现软件的内容大致上是摆在 etc, lib, bin, man等目录当中,分别代表『配置档、函式库、运行档、线上说明档』。好了,那么你是以 tarball 来安装时呢?如果是放在默认的 /usr/local 里面,由於 /usr/local 原本就默认这几个目录了,所以你的数据就会被放在:
但是如果你每个软件都选择在这个默认的路径下安装的话,那么所有的软件的文件都将放置在这四个目录当中,因此,如果你都安装在这个目录下的话,那么未来再想要升级或移除的时候,就会比较难以追查文件的来源罗!而如果你在安装的时候选择的是单独的目录,例如我将apache 安装在 /usr/local/apache 当中,那么你的文件目录就会变成:
呵呵!单一软件的文件都在同一个目录之下,那么要移除该软件就简单的多了!只要将该目录移除即可视为该软件已经被移除罗!以上面为例,我想要移除apache 只要下达『rm -rf /usr/local/apache』就算移除这个软件啦!当然罗,实际安装的时候还是得视该软件的Makefile 里头的 install 资讯才能知道到底他的安装情况为何的。因为例如 sendmail的安装就很麻烦......
这个方式虽然有利於软件的移除,但不晓得你有没有发现,我们在运行某些命令的时候,与该命令是否在PATH 这个环境变量所记录的路径有关,以上面为例,我的 /usr/local/apache/bin肯定是不在 PATH 里面的,所以运行 apache 的命令就得要利用绝对路径了,否则就得将这个/usr/local/apache/bin 加入 PATH 里面。另外,那个 /usr/local/apache/man也需要加入 man page 搜寻的路径当中啊!
除此之外, Tarball 在升级的时候也是挺困扰的,怎么说呢?我们还是以 apache来说明好了。WWW 服务器为了考虑互动性,所以通常会将 PHP+MySQL+Apache 一起安装起来 (详细的资讯请参考服务器架设篇),果真如此的话,那么每个软件在安装的时候『都有一定的顺序与程序!』因为他们三者之间具有相关性,所以安装时必需要三者同时考虑到他们的函式库与相关的编译参数。
假设今天我只要升级 PHP 呢?有的时候因为只有涉及动态函式库的升级,那么我只要升级 PHP 即可!其他的部分或许影响不大。但是如果今天 PHP 需要重新编译的模块比较多,那么可能会连带的,连 Apache 这个程序也需要重新编译过才行!真是有点给他头痛的!没办法啦!使用tarball 确实有他的优点啦,但是在这方面,确实也有他一定的伤脑筋程度。
由於 Tarball 在升级与安装上面具有这些特色,亦即 Tarball 在反安装上面具有比较高的难度 (如果你没有好好规划的话~),所以,为了方便 Tarball 的管理,通常鸟哥会这样建议使用者:
MANPATH /usr/local/software/man这样才可以使用 man 来查询该软件的线上文件罗!
读万卷书不如行万里路啊!所以当然我们就来给他测试看看,看你是否真的了解了如何利用Tarball 来安装软件呢?我们利用时间服务器 (network time protocol) ntp 这个软件来测试安装看看。先请到http://www.ntp.org/downloads.html这个目录去下载文件,请下载最新版本的文件即可。或者直接到鸟哥的网站下载 2009/05 公告释出的稳定版本:
http://vbird.dic.ksu.edu.tw/linux_basic/0520source/ntp-4.2.4p7.tar.gz
假设我对这个软件的要求是这样的:
那么你可以依照底下的步骤来安装测试看看 (如果可以的话,请你不要参考底下的文件数据,先自行安装过一遍这个软件,然后再来对照一下鸟哥的步骤喔!)。
[root@www ~]# cd /usr/local/src <==切换目录 [root@www src]# tar -zxvf /root/ntp-4.2.4p7.tar.gz <==解压缩到此目录 ntp-4.2.4p7/ <==会创建这个目录喔! ntp-4.2.4p7/libopts/ ....(底下省略).... [root@www src]# cd ntp-4.2.4p7/ [root@www ntp-4.2.4p7]# vi INSTALL <==记得 README 也要看一下! # 特别看一下 28 行到 54 行之间的安装简介!可以了解如何安装的流程喔! |
[root@www ntp*]# ./configure --help | more <==查询可用的参数有哪些 --prefix=PREFIX install architecture-independent files in PREFIX --enable-all-clocks + include all suitable non-PARSE clocks: --enable-parse-clocks - include all suitable PARSE clocks: # 上面列出的是比较重要的,或者是你可能需要的参数功能! [root@www ntp*]# ./configure --prefix=/usr/local/ntp \ > --enable-all-clocks --enable-parse-clocks <==开始创建makefile checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes ....(中间省略).... checking for gcc... gcc <==也有找到 gcc 编译器了! ....(中间省略).... config.status: creating Makefile <==现在知道这个重要性了吧? config.status: creating config.h config.status: executing depfiles commands |
一般来说 configure 配置参数较重要的就是那个 --prefix=/path 了,--prefix 后面接的路径就是『这个软件未来要安装到那个目录去?』如果你没有指定 --prefix=/path 这个参数,通常默认参数就是 /usr/local 至於其他的参数意义就得要参考 ./configure --help 了!这个动作完成之后会产生 makefile 或 Makefile 这个文件。当然啦,这个侦测检查的过程会显示在萤幕上,特别留意关於 gcc 的检查,还有最重要的是最后需要成功的创建起 Makefile 才行!
[root@www ntp*]# make clean; make [root@www ntp*]# make check [root@www ntp*]# make install # 将数据给他安装在 /usr/local/ntp 底下 |
整个动作就这么简单,你完成了吗?完成之后到 /usr/local/ntp 你发现了什么?
我们在本章一开始介绍了为何需要进行软件的升级,这是很重要的喔!那假如我是以Tarball 来进行某个软件的安装,那么是否当我要升级这个软件时,就得要下载这个软件的完整全新的Tarball 呢?举个例子来说,鸟哥帮昆山资传系架了个讨论区在 http://www.dic.ksu.edu.tw/phpbb3这个网址,这个讨论区是以 phpBB 这个软件来架设的,而鸟哥的讨论区版本为 phpbb3.0.4.tar.gz,目前 (2009/06) 最新释出的版本则是 phpbb3.0.5.tar.gz 。那我是否需要下载全新的phpbb3.0.5.tar.gz 这个文件来升级原本的旧程序呢?
事实上,当我们发现一些软件的漏洞,通常是某一段程序码写的不好所致。因此,所谓的『升级原始码』常常是只有更改部分文件的小部分内容而已。既然如此的话,那么我们是否可以就那些被更动的文件来进行修改就可以咯?也就是说,旧版本到新版本间没有更动过的文件就不要理他,仅将有修订过的文件部分来处理即可。
这有什么好处呢?首先,没有更动过的文件的目标档 (object file) 根本就不需要重新编译,而且有更动过的文件又可以利用 make 来自动 update (升级),如此一来,我们原先的配置 (makefile 文件里面的守则) 将不需要重新改写或侦测!可以节省很多宝贵的时间呢 (例如后续章节会提到的核心的编译!)
从上面的说明当中,我们可以发现,如果可以将旧版的原始码数据改写成新版的版本, 那么就能直接编译了,而不需要将全部的新版Tarball 重新下载一次呢!可以节省频宽与时间说!那么如何改写原始码?难道要我们一个文件一个文件去参考然后修订吗?当然没有这么没人性!
我们在第十二章、正规表示法的时候有提到一个比对文件的命令,那就是diff,这个命令可以将『两个文件之间的差异性列出来』呢!那我们也知道新旧版本的文件之间,其实只有修改一些程序码而已,那么我们可以透过 diff 比对出新旧版本之间的文字差异,然后再以相关的命令来将旧版的文件升级吗?呵呵!当然可以啦!那就是 patch 这个命令啦!很多的软件开发商在升级了原始码之后,几乎都会释出所谓的 patch file,也就是直接将原始码 update 而已的一个方式喔!我们底下以一个简单的范例来说明给你了解喔!
关於 diff 与 patch 的基本用法我们在第十二章都谈过了,所以这里不再就这两个命令的语法进行介绍,请回去参阅第十二章的内容。这里我们来举个案例解释一下好了。假设我们刚刚计算三角函数的程序 (main) 历经多次改版,0.1 版仅会简单的输出, 0.2 版的输出就会含有角度值,因此这两个版本的内容不相同。如下所示,两个文件的意义为:
请您先下载这两个文件,并且解压缩到你的 /root 底下。你会发现系统产生一个名为 main-0.1 的目录。该目录内含有五个文件,就是刚刚的程序加上一个 Makefile 的守则文件。你可以到该目录下去看看 Makefile 的内容,在这一版当中含有 main 与 clean 两个标的功能而已。至於 0.2 版则加入了 install 与 uninstall 的守则配置。接下来,请看一下我们的作法罗:
[root@www ~]# tar -zxvf main-0.1.tgz [root@www ~]# cd main-0.1 [root@www main-0.1]# make clean main [root@www main-0.1]# ./main version 0.1 Please input your name: VBird Please enter the degree angle (ex> 90): 45 Hi, Dear VBird, nice to meet you. The Sin is: 0.71 The Cos is: 0.71 |
与之前的结果非常类似,只是鸟哥将 Makefile 直接给您了!但如果你下达 make install 时,系统会告知没有 install 的 target 啊!而且版本是 0.1 也告知了。那么如何升级到 0.2 版呢?透过这个 patch 文件吧!这个文件的内容有点像这样:
[root@www main-0.1]# vim ~/main_0.1_to_0.2.patch diff -Naur main-0.1/cos_value.c main-0.2/cos_value.c --- main-0.1/cos_value.c 2009-06-09 22:52:33.000000000 +0800 +++ main-0.2/cos_value.c 2009-06-12 00:45:10.000000000 +0800 @@ -6,5 +6,5 @@ { float value; ....(底下省略).... |
上面表格内有个底线的部分,那代表使用 diff 去比较时,被比较的两个文件所在路径,这个路径非常的重要喔!因为 patch 的基本语法如下:
patch -p数字 < patch_file
特别留意那个『 -p数字』,那是与 patch_file 里面列出的档名有关的资讯。假如在patch_file 第一行写的是这样:
*** /home/guest/example/expatch.old
那么当我下达『 patch -p0 < patch_file 』时,则升级的文件是『 /home/guest/example/expatch.old』,如果『 patch -p1 < patch_file』,则升级的文件为『home/guest/example/expatch.old』,如果『patch-p4 < patch_file』则升级『expatch.old』,也就是说, -pxx 那个 xx 代表『拿掉几个斜线(/)』的意思!这样可以理解了吗?好了,根据刚刚上头的数据,我们可以发现比较的文件是在 main-0.1/xxx 与 main-0.2/xxx ,所以说,如果你是在 main-0.1 底下,并且想要处理升级时,就得要拿掉一个目录 (因为并没有 main-0.2 的目录存在,我们是在当前的目录进行升级的!),因此使用的是 -p1 才对喔!所以:
[root@www main-0.1]# patch -p1 < ../main_0.1_to_0.2.patch patching file cos_value.c patching file main.c patching file Makefile patching file sin_value.c # 请注意,鸟哥目前所在目录是在 main-0.1 底下喔!注意与 patch 文件的相对路径! # 虽然有五个文件,但其实只有四个文件有修改过喔!上面显示有改过的文件! [root@www main-0.1]# make clean main [root@www main-0.1]# ./main version 0.2 Please input your name: VBird Please enter the degree angle (ex> 90): 45 Hi, Dear VBird, nice to meet you. The sin(45.000000) is: 0.71 The cos(45.000000) is: 0.71 # 你可以发现,输出的结果中版本变了,输出资讯多了括号 () 喔! [root@www main-0.1]# make install <==将他安装到 /usr/local/bin 给大家用 cp -a main /usr/local/bin [root@www main-0.1]# main <==直接输入命令可运行! [root@www main-0.1]# make uninstall <==移除此软件! rm -f /usr/local/bin/main |
很有趣的练习吧!所以你只要下载 patch file 就能够对你的软件原始码升级了!只不过升级了原始码并非软件就升级!你还是得要将该软件进行编译后,才会是最终正确的软件喔!因为 patch 的功能主要仅只是升级原始码文件而已!切记切记!此外,如果你 patch 错误呢?没关系的!我们的 patch 是可以还原的啊!透过『 patch -R < ../main_0.1_to_0.2.patch 』就可以还原啦!很有趣吧!
例题:
如果我有一个很旧版的软件,这个软件已经升级到很新的版本,例如核心,那么我可以使用 patch file 来升级吗?
答:
这个问题挺有趣的,首先,你必须要确定旧版本与新版本之间『确实有释出 patch file 』才行,以 kernel 2.2.xx 及 2.4.xx 来说,这两者基本上的架构已经不同了,所以两者间是无法以 patch file 来升级的。不过, 2.4.xx 与 2.4.yy 就可以升级了。不过,因为 kernel每次推出的 patch 文件都仅针对前一个版本而已,所以假设要由 kernel 2.4.20 升级到 2.4.26 ,就必须要使用 patch 2.4.21, 2.4.22, 2.4.23, 2.4.24, 2.4.25, 2.4.26 六个文件来『
依序升级』才行喔!当然,如果有朋友帮你比对过2.4.20 与 2.4.26 ,那你自然就可以使用该 patch file 来直接一次升级罗!
|