发布软件
程序发布的主要问题就是要保证包含所有的文件以及确切的版本。幸运的是,网络程序社区已经发展出一个健壮的方法集合可以很多的解决这个问题。这些方法包括:
使用在所有的Unix机器上均可用的标准工具将所有的组件文件打包进入一个包文件中
控制软件包的版本号
包文件采用包含版本号的命名约定从而用户可以很容易分辨出他们正在处理的版本
包中子目录的使用可以保证当文件由包文件中解压出来时,他们就会位于一个单独的目录中,这样就不会弄混哪些包含在包文件中而哪些没有
这些方法的发展就意味着程序可以很容易并且可靠的发布。程序安装的简便性是另一个问题,因为他会依赖于程序与所要安装的系统,但是至少我们可以保证我们拥有合适的组件文件。
patch程序
当
程序发布以后,几乎是不可避免的出现用户发现bug或是程序的作者希望执行程序增加或是更新的情况。当作者将程序作为二进制文件发布时,他们通常只是简单
的传递新的二进制文件。有时(更为经常),提供者只是简单的放出程序的一个新版本,通常是晦涩引用以及关于程序修改内容的少量信息。
另一个方面,将我们的软件作为一个源码包进行发布是一个好主意,因为这可以允许用户知道我们是如何实现的以及如何使用这些特性。也可以允许用户检测程序实际所做的工作并且可以重用部分源代码。
然而,例如Linux内核这样几十兆压缩源代码的重量级程序,传输内核源码的更新集合将会占用大量的资源,而事实上,在每个版本之间只有很少一部分的源代码进行了修改。
幸
运的,有一个实用程序可以解决这个问题:patch。他是由Larry
Wall编写的,他同时也编写了Perl程序语言。patch命令可以使得我们只发布两个版本之间相区别的部分,这样任何具有版本1文件以及一个由版本1
到版本2的区别文件的人就可以使用patch命令自己生成版本2文件。
如果我们由版本1文件开始,
This is file one
line 2
line 3
there is no line 4, this is line 5
line 6
然后我们创建版本2文件,
This is file two
line 2
line 3
line 4
line 5
line 6
a new line 8
我们可以使用diff命令来创建一个区别列表:
$ diff file1.c file2.c > diffs
diffs文件包含如下内容:
1c1
< This is file one
—
> This is file two
4c4,5
< there is no line 4, this is line 5
—
> line 4
> line 5
5a7
> a new line 8
这实际上是将一个文件修改为另一个文件的编辑器命令集合。假设我们有文件file1.c以及diffs文件,我们可以使用patch命令来更新我们的文件:
$ patch file1.c diffs
Hmm... Looks like a normal diff to me...
Patching file file1.c using Plan A...
Hunk #1 succeeded at 1.
Hunk #2 succeeded at 4.
Hunk #3 succeeded at 7.
done
$
现在patch命令就已经将文件file1.c修改为与file2.c相同的ywyr
patch还有一个小技巧:去补丁的能力。假如我们不喜欢这些更改并且退回我们原始的file1.c文件。没有问题,只需要再次使用patch命令,使用-R选项即可。
$ patch -R file1.c diffs
Hmm... Looks like a normal diff to me...
Patching file file1.c using Plan A...
Hunk #1 succeeded at 1.
Hunk #2 succeeded at 4.
Hunk #3 succeeded at 6.
done
$
file1.c已经回退到其原始状态了。
patch还有许多其他的选项,但是通常很善于由其输入来确定我们正在尝试做什么,然后简单的完成这些事情。如果patch命令失败,他就会创建一个以.rej为扩展名包含不能进行补丁操作的部分。
当我们正在处理软件补丁时,使用diff -c选项是一个好主意,这会生成一个"context diff"。这会在每一个修改之后与之后提供几行文本,从而patch在应用补丁之前可以验证内容匹配,而补丁文件也更容易阅读。
其他的发布程序
Linux
程序与源码通常以包含版本号的名字,并且以.tar.gz或是.tgz的扩展名进行发布。这些是使用gzip压缩的TAR文件,也就是所熟知的
tarball。如果我们使用通常的tar,我们必须通过两步来处理这些文件。下面我们来为我们的程序创建一个gzip文件。
$ tar cvf myapp-1.0.tar main.c 2.c 3.c *.h myapp.1 Makefile5
main.c
2.c
3.c
a.h
b.h
c.h
myapp.1
Makefile5
$
现在我们有一个TAR文件。
$ ls -l *.tar
-rw-r--r-- 1 neil
$
我们可以使用gzip压缩程序使其变得更小:
$ gzip myapp-1.0.tar
$ ls -l *.gz
-rw-r--r-- 1 neil
$
正如我们所看到的,其结果在尺寸上非常小。.tar.gz然后可以简单的重命名为.tgz扩展名:
$ mv myapp-1.0.tar.gz myapp_v1.tgz
以逗点和三个字符进行重命名的习惯似乎是对Windows软件的让步,因为与Linux和Unix不同,Windows很依赖正在处理的正确的扩展名。要得到我们的文件,我们可以解压并且由tar文件中释放这些文件:
$ mv myapp_v1.tgz myapp-1.0.tar.gz
$ gzip -d myapp-1.0.tar.gz
$ tar xvf myapp-1.0.tar
main.c
2.c
3.c
a.h
b.h
c.h
myapp.1
Makefile5
$
使用GNU版本的tar,事情会变得更为简单--我们可以一步创建压缩归档:
$ tar zcvf myapp_v1.tgz main.c 2.c 3.c *.h myapp.1 Makefile5
main.c
2.c
3.c
a.h
b.h
c.h
myapp.1
Makefile5
$
我们也可以进行简单的解压:
$ tar zxvf myapp_v1.tgz
main.c
2.c
3.c
a.h
b.h
c.h
myapp.1
Makefile5
$
如果我们希望知道归档的内容而不实际的进行解压,我们可以使用另一个不同的tar ztvf选项来调用tar程序。
我们在前面使用tar作为例子,而并没有描述除必须的选项以外的其他选项。下面我们简单的看一下tar命令以及一些常用的选项。正如由例子中所看到的,基本语法为:
tar [options] [list of files]
列
表中的第一个项目为目标,尽管我们只是处理文件,他可以处理设备。列表中的其他项目要添加到一个新的或是已存在的归档中,这依赖于我们所使用的选项。这个
列表也可以包含目录,在这种情况下,所有子目录默认情况下都会包含在文件中。如果我们释放文件,没有必要指定名字,因为tar会保存完全路径。
在这一部分,我们使用了六个不同选项的组合:
c:创建一个新的归档
f:指定目标是一个文件而不是一个设备
t:列出一个归档中的内容而不实际释放
v:tar显示出处理消息
x:由归档中释放文件
z:在GNU tar中使用gzip过滤归档
tar命令还有更多的选项允许我们对于命令的操作以及他所创建的文档进行更好的控制。查看tar手册页可以得到更为详细的信息。
阅读(520) | 评论(0) | 转发(0) |