分类: BSD
2008-03-20 17:58:43
名称:
提供由ports/packages来升级/安装新的软件的工具
语法:
portupgrade
[-habcCDDfFiknNOpPPqrRsuvwWy]
[-A
command]
[-B
command]
[-l
file]
[-L
format]
[-S
command]
[-x
pkgname_glob]
[[-o
origin]
[-m
make_args]
[-M
make_env]
pkgname_glob
...]
描述:
portupgrade是提供由ports/packages来升级/安装新软件的功能的工具,portinstall等价于portupgrade
–N。
在阅读该说明书之前,请务必理解每个port/package都有两种不同类型的ports/packages:
required(必需的):一个port/package构成、运行所必须的ports/packages,在Makefiles中分别以宏BUILD_DEPENDS
和RUN_DEPENDS指定。
dependent(依赖的):一个port/package需要的ports/packages。
警告:
o
请仔细阅读本手册并了解你用portupgrade要做什么。
o
建议先执行pkgdb –F,一次升级大量的有不一致的package数据库的packages必然会导致坏的结果。
o
portupgrade允许你不重新编译、安装依赖的packages,因此可能会导致二进制的兼容问题,必要时别忘了使用-f、-r 、-R 参数。
o
当portupgrade执行中请勿中断,否则你将得到一个修改了一部分、不完整的package数据库,即使你什么也没做错,package数据库也可能被破坏,这个时候你需要执行pkgdb
–fu重建数据库,把它从coredumping中营救回来。
o
切勿偷懒,务必备份先前的数据及配置文档,包括在/var/db/pkg 的package数据库。
参数:
portupgrade支持以下参数:
pkgname_glob
定义一个pkgname,支持通配符(名字是pkg_info显示的内容,不带版本号)。更进一步的细节参看pkg_glob(1)。。
-h
--help显示帮助选项
-a
--all
升级所有已安装的过时的ports,相当于pkgname_glob中的*
-A CMD
--afterinstall CMD
在每次安装以后以root身份执行CMD代替的命令
-b
--backup-packages
备份老版本的ports,这些数据会暂存于PKG_TMPDIR 及 TMPDIR定义的位置。
-B
CMD
--beforebuild
CMD
在每次安装之前执行CMD代替的命令,如果命令执行失败,则跳过该安装。
下面是一些典型应用:
portupgrade
-B 'cvs update' 'gnome*'
portupgrade
-B 'ports_glob -M $(pwd) | (cd ../..; xargs cvs up)'
slave/port
portupgrade
-aB 'test ! `make –V IS_INTERACTIVE`'
-c
--clean
每次编译前执行make
clean,这是默认值,参看下面的-w选项。
-C
--cleanup
每次安装后执行make
clean,这是默认值,参看下面的-W选项。
-D
--distclean
如果checksum失败就删除错误的文件并重试。在每次fetch或是build之前执行 make distclean。
-f
--force
强制执行,即使是降级或同一版本,或者用户在pkgtools.conf里面用HOLD_PKGS指定保留的。
-F
--fetch-only
仅仅获取文件或packages(如果指定了-P选项),而不做upgrade、install等操作。该参数对于一次取得所有需要的文件很有用。
默认情况下,当一个port/package安装失败的话,依赖于它的ports/packages将被忽略。
-i
--interactive
打开互动模式,在进行安装或升级前会征求你的同意。该选项包含了-v选项。
-k
--keep-going
即使某些依赖的package更新失败也继续执行。
-l
FILE
--results-file
FILE
将更新结果以FILE文件名保存,默认情况下portupgrade是不保存的。
-L
FORMAT
--log-file
FORMAT
为每个port保存一个记录文件,格式为中规定的,如果FORMAT中没有包含一个%,则默认是%s::%s,类别和port名字作为变量。
-m
--make-args
在每次make(1)命令后加额外的参数。
-M
--make-env
在每次make(1)命令前加额外的参数。
-n
--noexecute
不实际执行安装或升级动作,只显示会有何变化。该选项包含了-v,否定-i和-y。
-N
--new
当指定的package没有安装的情况下,安装一个新的port/package,它所依赖的ports/packages也一起安装/升级。
如果该选项被指定,可以像pkgname glob 参数一样定义一个portorigin glob来说明要安装哪个port,更多信息参看。
-o
ORIGIN
--origin
ORIGIN
定义一个port在某个package之后升级。
-O
--omit-check
忽略依赖性检测,默认情况下,portupgrade会花费大量的时间去计算所有packages的依赖性关系。如果之前已经执行了pkgdb –F,那么可以用该参数来忽略它。
-p
--package
每个指定的port都安装/升级以后建立一个package,如果在命令行指定了它依赖的包(包括指定了-r选项的情况),也为它们建立package。
-P
-use-packages
使用预编译的 package 而不是 ports 来进行安装,
首先搜索
PKG_PATH 中指定的本地目录,
如果没有找到,则调用从远程站点下载。
如果本地没有找到,
而且远程站点也没有成功地下载预编译包,则使用 ports。
-PP
--use-packages-only
即使在本地目录和远程站点上都找不到也不用port方式。此时仍然需要保持ports
tree到最新的。
-q
--noconfig
不去读取配置文件:$PREFIX/etc/pkgtools.conf
-r
--recursive
升级所有依赖该package的packages
-R
--upward-recursive
升级所有该package依赖的packages。如果同时指定了-F,将递归的下载所有的packages,包括全新未安装过的packages,然后卸载升级这些port时需要的ports。
-s
--sudo
需要的时候以状态执行命令
S
CMD
--sudo-command
CMD
为sudo指定一个可选的命令,例如:'su root -c %s '默认情况下是sudo
-u
--uninstall-shlibs
不保留旧的共享库,默认情况下为了安全portupgrade保留旧的共享库,更多细节参看 帮助页中的-P选项。
-v
--verbose
开启verbose输出。
-w
--noclean
每次编译前不做make
clean操作,参看上面的-c选项。
-W
--nocleanup
每次安装后不做make
clean操作,参看上面的-C选项。
-x
GLOB
--exclude
GLOB
将符合glob样式的packages排除在外,在响应-r或-R时生效。例如升级所有依赖于Xfree86的除了Xfree86之外的packages:
portupgrade -rx XFree86 XFree86
-y
--yes
对所有问题都回答yes。该选项包含了-v,否定-n。
技术细节
portuupgrade可以通过ports或packages升级已经安装过的packages,不需要重新安装必需或依赖的packages。
下面是portupgrade的工作流程:
1:如果没有指定-P选项,跳到4;否则搜索
PKG_PATH 中指定的本地目录中十分有更新的package tarball,如果找到,跳到5。
2:通过从远程站点下载最新的包,如果下载的是最新的包,跳到5;如果-P出现两次(例如-PP)并且下载的包虽然不是最新的但比本机的新,跳到5。
3:如果-P出现两次(例如-PP),任务结束。
4:编译指定的已安装包响应的port。
5:更新那些依赖于指定包的packages的依赖信息(个人理解为版本等信息)。
6:通过.备份命令中指定包当前的版本。注意如果是像XFree86这样的大妖怪,备份的包会很大,请确定有足够的空间(查看环境变量ENVIRONMENT就知道在哪了)来保存它,也许不久的将来会有个新的选项来忽略这个操作。
7:备份命令中指定的包当前安装的版本注册的文件(个人理解为那些配置文件)。
8:强制卸载命令中指定的包,保存共享库除非-u选项被指定。
9:根据1、2、3步骤决定的方式通过ports或package来安装新版本。
10:如果安装失败:
10.1恢复在步骤6里面备份的包
10.2恢复在步骤7里面备份的注册文件
10.3恢复在步骤5里面的包依赖信息
11:删除旧的依赖信息
12:运行portsclean –L删除重复的依赖信息数据库,备份老的数据库。
13:运行pkgdb –aF更新旧的依赖信息,重建+REQUIRED_BY文件。
例子
o
升級glib:
portupgrade glib
如你所见,可以忽略版本号。如果安装了多个版本,则所有的都将被更新,除非他们共享一个port源(大概有如下两种情况,见下),例如你可能有foo-1.02和foo-1.03两个版本的软件,这个时候需要先运行pkgdb –F。
例子一:一个用ports安装,一个是源代码编译安装的,这个时候portupgrade会提示是否卸载那个编译安装的。
例子二:随着时间的演进,不同时间安装的软体会有不同版本的释出,而且不同软体相依的版本号也不同,所以往往会造成同一个软体安装过多版本的情形发生。这里我必须声明的是,虽然套件名称相同,可是可能没办法上下兼容,因此造成有些软体必须依赖比较旧的版本,而有些软体必须依赖比较新的版本,如果有这种情形发生的话,那么二个版本的存在是正常的。
Q:portsupgrade过程中,对于"共享同一ports源"
应该将所有不同版本都升级为统一版本.那么"不同ports源"是,他怎么去判断是否要升级?不太理解了.
A:我的理解:不同port源的东东可以认为是两个东西,所以portupgrade的时候可能只跟某一个有关联,另外一个只不过也叫那个名字而已。
o升级Xfree86和Mesa,并且以-DWANT_GGI来编译Mesa:
portupgrade XFree86 -m '-DWANT_GGI' Mesa
当portupgrade处理多个包的时候,会自动地按依赖顺序挑选packages。
-m / --make-args是指定的传递給的选项。
O升级所有GNOME的packages,并将build日志记录在文件:/var/tmp/portupgrade-_category_::_portname_.log中
portupgrade -L /var/tmp/portupgrade-%s::%s.log '*gnome*'
既可以如同那样使用通配符,也可以使用perl的扩展正则表达式。扩展正则表达式的使用方法是在表达式之前加":",上面的例子可以写成这样::gnome。
-L / --log-prefix是告诉portupgrade为每个port保存一个记录文件,不管是否有这个选项,portupgrade都会观察每个port的build过程,当某个失败的时候会分析产生的原因。
O采用verbose模式升级sawfish和它所依赖的packages,升级之后建立binary
packages。
portupgrade -Rpv
sawfish
-R / --upward-recursive告诉portupgrade根据依赖信息递归的升级所有依赖的packages。在上面的例子中,rep-gtk, librep,imlib, gnomelibs, XFree86等都会被升级。
-p / --package告诉portupgrade升级以后建立个package。
-v / --verbose是开启verbose输出的选项。
O升级glib和依赖与它的packages,每个upgrade都会要求确认。
portupgrade -ri glib
-r / --recursive升级所有依赖该package的packages,在上例中,gtk和所有GNOME有关的packages都会被升级。
-i / --interactive告诉portupgrade在进行操作前征求你的同意。
O重新编译、安装所有依赖与sdl的ports,但sdl除外
portupgrade -rfx sdl sdl
-f / --force即使根据版本比较不需要升级也强制执行。
-x / --exclude指定了排除需要符合的模式。
O重新编译、安装在2001-09-20之前安装的ports
portupgrade -f
'<2001-09-20'
还可以选择一个时间范围。
O重新编译、安装依赖与png且安装在它之前的packages
portupgrade -fr png -x
'>=png'
你可以选择一个package去指定时间。
O立即下载升级所有已安装packages所需的文件,但是并不执行升级操作。
portupgrade
-aFR
-a /
--all等于指定了*
-F /
--fetch告诉portupgrade仅获取文件,而不做upgrade操作。
除了-a之外,指定-R选项是很有必要的,因为有些被upgrade的ports会需要一些新的未曾安装过的ports。
O用ghostscript-afpl替换ghostscript-gnu
portupgrade -o print/ghostscript-afpl ghostscript-gnu
-o /
--origin最初是用在那些FreeBSD4.2之前的缺少了源的过时package,这个例子显示了另外一种有用的功能,像这样用,可以让那些依赖与老的package(ghostscript-gnu)替换为新的package(ghostscript-afpl),不会有任何的问题。
O采用packages方式升级glib,如有必要,从远程ftp站点上下载。
portupgrade -P
glib
-P /
--use-packages告诉portupgrade使用 packages 而不是 ports。
O用光盘里的packages升级大量的程序,但在这之前,我们先看看什么会有变化:
env PKG_PATH=/mnt/cdrom/packages/All portupgrade
-anPP
-n /
--noexecute告诉portupgrade不实际执行安装或升级动作,只显示会有何变化。
两个-P告诉portupgrade只用packages方式;如果升级它需要的packages(*.tgz)找不到就不升级。
如果你不想portupgrade在光盘上找不到文件就去下载的话,把PKG_FETCH设置为/bin/false。
小技巧
O执行完升级操作以后,强烈建议执行pkgdb –F修复由新装的packages引起的被破坏的依赖性。
O大量升级时使用:
portupgrade -aPPR
O有疑惑的时候,使用portupgrade的-n和-i选项看看会产生什么效果,或者使用来看它是如何扩展patter的。
O为了有效且正确的升级,请在必要时执行pkgdb –F以保持它们的依赖性关系。每次cvsup更新完ports以后要执行portsdb –Uu来更新ports INDEX资料库。
O可以尝试用代替来确定是否可以升级,它和pkg_version使用方法大同小异,但速度要快。类似的,portversion –c也是利用portupgrade来升级。
O可以尝试用来代替来卸载packages,它在pkg_delete基础上增加了可递归的反安装及共享库的保存功能。
O要清理没用的文件及编译中的临时文件、旧的共享库,请使用。
O要跟踪一个port的变化过程,请使用。
环境变量
PKG_DBDIR
已安装的package的数据库的位置,默认是/var/db/pkg
PORTSDIR
ports树的位置,默认是/usr/ports
PORTS_INDEX
ports INDEX的位置,默认是$PORTSDIR/INDEX
PORTS_DBDIR
ports数据库的位置,默认是$PORTSDIR
PKG_TMPDIR
TMPDIR portupgrade更新的时候备份文件的临时目录,如果没有设置的话使用/var/tmp,注意这个目录必须要有足够的空间,尤其是在更新一个大的package时,参见上面的技术细节章节。
PACKAGES
portupgrade建立packages的基础目录,默认是$PORTSDIR/packages
PKG_PATH
portupgrade查询packages的目录列表,以冒号分割,默认是$PACKAGES/All
PKG_SUFX
packages的后缀,默认是在bsd.port.mk
或
/etc/make.conf中定义的
PKGTOOLS_CONF
pkgtools的配置文件,默认是$PREFIX/etc/pkgtools.conf
PORTUPGRADE
portupgrade的默认选项(例如-v)
文件
/var/tmp 创建备份文件的临时目录,如果环境变量PKG_TMPDIR 或者TMPDIR没有指向一个合适的目录。
/var/db/pkg 默认的已安装的package的数据库的位置
/usr/ports
默认的ports树和ports数据库的位置
$PREFIX/etc/pkgtools.conf 默认的pkgtools的配置文件
其他相关
, , , , ,
, , , , ,
, , , ,
作者
Akinori MUSHA <>
Bugs
在编译/安装的时候快捷键Ctrl+z不起作用。
有时数据库会损坏,pkgtools命令因为segmentation fault错误而中断,运行pkgdb –fu重建数据库将解决此问题。
一些第三方或自己编译的packages会有不合法的package名字令portupgrade和相关工具恼怒异常,要将它们隐藏,在它们的目录下建一个名字叫+IGNOREME的文件(使用)