Bzip2 Howto <author>作者: <newline> David Fetter, <url url="mailto:dfetter@best.com" name="dfetter@best.com"> <newline> 译者:<newline> 谢昆中 HSIEH KUN-CHUNG, 台湾 中华民国 Taiwan, Republic of China (NOT People's Republic of China) (电子邮件 <tt><htmlurl url="mailto:linuxer.bbs@cis.nctu.edu.tw" name="linuxer.bbs@cis.nctu.edu.tw"></tt> 或<tt><htmlurl url="mailto:linux4tw@geocities.com" name="linux4tw@geocities.com"></tt> 网页 "Linux for Taiwan 台湾人的 Linux" <tt><htmlurl url="http://members.xoom.com/linux4tw/" name="http://members.xoom.com/linux4tw/"></tt> <newline> <date>版本 v1.92,1998年 8月18日 <abstract> 这份文件在教你如何使用新的 bzip2 压缩程式。目前的 sgml 版本被放在 EURO <url url="Bzip2-HOWTO.sgml" name="这□">,还有 "作者用的" sgml 档放在 <url url="http://www.best.com/~dfetter/Bzip2-HOWTO/Bzip2-HOWTO.sgml" name="这儿">。 </abstract> <!-- Table of contents --> <toc> <!-- Begin the document --> <sect>简介 <p> Bzip2 是个很棒的压缩资料用之新型演算法。大致上能够达到以它的对手 gzip 所产出的档案之 60-70% 左右的压缩率。 <p> 这份文件将教你几个 bzip2 的应用软体。 <p> 本文件的未来版将会讨论即将出现的 bzip2 程式库,该程式库 原bzip2 的作者 <url url="mailto:Julian_Seward@muraroa.demon.co.uk" name="Julian Seward"> 描述如下: <verb> 现在正致力於 bzip2 的下一个版本,它也将采用相同的 .bz2 档案格式; 主要增加的功能是一个像 zlib 的程式库。让我们可以从程式□头来读取和书写资料到这种格式的档案□。 </verb> <p> 本文件的未来版本也会包含是否应该 (以及如何)让 Linux kernel 使用 bzip2之议题的结论。 <sect1> <bf>沿革历史</bf> <sect2> v1.92 更新 <ref id="bzip2-binaries" name="取得 bzip2 二进位程式码"> 章节,加入 S.u.S.E.的。 <sect2> v1.91 <p> 在 <ref id="bzip2-with-tar" name="使用 bzip2 配合 tar 那章□">修正一个□例以及 弄清楚一些 shell 句子。感谢 Alessandro Rubini。 <p> 更新 buzzit 工具不会去 stomp 原来的 bzip2 压缩档。 <p> 新增 bgrep, 像 zgrep-的工具。 <sect2> v1.9 <p> 澄清 gcc 2.7.* 的问题。感谢 Ulrik Dickow 的热心指出。 <p> 加入 Leonard Jean-Marc 很棒的配合 tar <p> 加上 Linus Ãkerlund 的瑞典文版本。 <p> 依照 Arnaud Launay 的建议修正了 wu-ftpd 章节 <p> 把译文放到它们自己的位章节上。 <sect2> v1.8 <p> 把 buzzit 和 tar.diff 放到 sgml 文件□它们应该被放置的地方。 修正拼字与格式。感谢 Arnaud Launay 的协助我修正这份文件。:-) <p> 杀掉 xv 计画,因此大家不感兴趣。 <p> 加上 teasers 为本文件的未来版本。 <sect2> v1.7 <p> 加入 buzzit 公用程式。修正对 gnu tar 的修补。 <sect2> v1.6 <p> 加入 TenThumbs 的 Netscape 致能者。 <p> 以及依据它的建议更改 lesspipe.sh 。它现在可以工作的更好了。 <sect2> v1.5 <p> 加入 Arnaud Launay 的法文译本,以及他的 wu-ftpd 档。 <sect2> v1.4 <p> 加入 Tetsu Isaji 的日文译本。 <sect2> v1.3 <p> 加入 Ulrik Dickow 给 19.30 或更高版本用的 .emacs 档□ <p>(还有修正给 emacs用的 jka-compr.el 修补档。糟了! Bzip2 还没有(?) "append" 的旗标选项。) <sect2> v1.2 <p> 加入对 emacs 的修补,让它可以自动地办识出 .bz2 档。 <sect2> v1.1 <p> 加入对 emacs <sect2> v1.0 <p> 第一回合。 <sect>取得 bzip2<label id="get-bzip2"> <p> Bzip2 的主网页在 <url url="http://www.muraroa.demon.co.uk/" name= "英国的主网站">。 美国的映射站在 <url url="http://www.digistar.com/bzip2/index.html" Name="这□">。你也可以在 Red Hat 的ftp 站□ <url url="ftp://ftp.redhat.com/pub/contrib" name="找到">。 <sect1>Bzip2-HOWTO 各种语言版本 <p> 说法语的人可以看看 Arnaud Launay 的法文文件。 网页版本在 <url url="http://www.freenix.fr/linux/HOWTO/mini/Bzip2.html" name="这□">,你可以用 ftp <url url="ftp://ftp.lip6.fr/pub/linux/french/docs/HOWTO/mini/Bzip2.gz" name="来取得"> 你可以用<url url="mailto:zoro@mygale.org" name="电子邮件">来连络Arnaud <p> 说日语的人可以看看 Tetsu Isaji的 <url url="http://jf.gee.kyoto-u.ac.jp/JF/JF.html" name="日文译本">。 你可以用上Isaji的 <url url="http://www2s.biglobe.ne.jp/~kaien/" name="网站">,或是用 <url url="mailto:isaji@mxu.meshnet.or.jp" name="电子邮件">的方式。 <p> 说瑞典语的朋友可以参阅 Linus Ãkerlund 的瑞典文译本 <url url="http://user.tninet.se/~uxm165t/linux_doc.html" name="按这">。你可以用 <url url="mailto:uxm165t@tninet.se" name="电子邮件"> 与 Linus 连络。 <sect1>取得 bzip2 未编译的二进位档<label id="bzip2-binaries"> <p>查一下主网站。 <p>Debian 的Intel 二进位程式码在 <url url="ftp://ftp.debian.org/debian/dists/stable/main/binary-i386/utils/bzip2_0.1pl2-5.deb" name="这□">。 <p>Red Hat的 alpha 二进位程式码在 <url url="ftp://ftp.redhat.com/pub/redhat/redhat-5.1/alpha/RedHat/RPMS/bzip2-0.1pl2-1.alpha.rpm" name="这□">。 <p>Red Hat的 Intel 二进位程式码在 <url url="ftp://ftp.redhat.com/pub/redhat/redhat-5.1/i386/RedHat/RPMS/bzip2-0.1pl2-1.i386.rpm" name="这□">。 <p>Red Hat的 SPARC 二进位程式码在 <url url="ftp://ftp.redhat.com/pub/redhat/redhat-5.1/sparc/RedHat/RPMS/bzip2-0.1pl2-1.sparc.rpm" name="这□">。 <p> Slackware的 Intel 二进位程式码在 <url url="ftp://www.cdrom.com/pub/linux/slackware-3.5/slakware/a1/bzip2.tgz" name="这□">。 <p> S.u.S.E.的 Intel 二进位程式码在 <url url="ftp://ftp.suse.com/pub/SuSE-Linux/5.2/suse/ap1/bzip.rpm" name="这□">。 你也可以从许多相类似的映射站得取得档案。 <sect1>取得 bzip2 原始程式 <p>你可以从官方的网站 (看 <ref id="get-bzip2" name="Getting Bzip2"> ,或是 Red Hat 也有 <url url="ftp://ftp.redhat.com/pub/contrib/SRPMS/bzip2-0.1pl2-1.src.rpm" name="它">)。 <sect1>编译 bzip2 给你的机器使用 <p><bf>如果你有 gcc 2.7.*</bf>,将下面这行 <tscreen><verb> CFLAGS = -O3 -fomit-frame-pointer -funroll-loops </verb></tscreen> <p>改成 <tscreen><verb> CFLAGS = -O2 -fomit-frame-pointer </verb></tscreen> <p> 也就是,把 -O2 改成 -O3 并把 -funroll-loops删掉。你也可以加入任何你在编译 kernel 时的 -m* 旗标 (例如像 -m486)。 <p> 避免使用 -funroll-loops 是最重要的了,因为它会造成许多的 gcc 2.7产生错误的程式码,以及全部的 gcc 2.7 产生速度慢又较胖的程式码。 对其他的编译器 (lcc, egcs, gcc 2.8.x) 使用内定的 CFLAGS 就没问题。 <p> 之後,只需 <tt/make/ 它,然後依照 README 来安装它。 <sect>使用 bzip2 <p>请参阅很棒的手册 :) <sect>配合 tar来使用 bzip2<label id="bzip2-with-tar"> <p>下面有三种配合 tar 使用 bzip2 的方法,也就是 <sect1>容易设立: <p>这个方法跟本就不必做设定。执行解开bzip2'd 的 tar包裹, 在现行目录底下有个 foo.tar.bz2,执行 <tscreen><verb> /path/to/bzip2 -cd foo.tar.bz2 | tar xf - </verb></tscreen> <p>成功了,但可能有常需输入的小缺点。 <sect1>容易设立,容易使用,不需要 root 的特权: <p> 感谢 <url url="mailto:leonard@sct1.is.belgacom.be" name="Leonard Jean-Marc"> 贡献这个小技巧。也谢谢 <url url="mailto:rubini@morgana.systemy.it" name="Alessandro Rubini"> 从 csh□分类 出 bash 的。 <p>在你的 .bashrc□,你可以加入像下面这行: <tscreen><verb> alias btar='tar --use-compress-program /usr/local/bin/bzip2 ' </verb></tscreen> <p>在你的 .tcshrc 或 .cshrc□,可用下面这行相同的: <tscreen><verb> alias btar 'tar --use-compress-program /usr/local/bin/bzip2' </verb></tscreen> <sect1>同样是容易使用,但需要 root 来存取。 <p>用下面来方法来修补 gnu tar 1.12: <tscreen><verb> cd tar-1.12/src; patch < /path/to/tar.diff </verb></tscreen> 编译、安装它,你已准备就绪了。用"which tar" 和 "which bzip2"来确认这两个 tar 和 bzip2 有在你的 $PATH □。要使用新的 tar,只需 <tscreen><verb> tar xyf foo.tar.bz2 </verb></tscreen> 来压缩档案。 <p>要制作新的压缩档,同样地: <tscreen><verb> tar cyf foo.tar.bz2 档名1 档名2 档名3...目录1 目录2... </verb></tscreen> <p> 下面是修补的地方: <verb> *** tar.c Thu Jun 11 00:09:23 1998 --- tar.c.new Thu Jun 11 00:14:24 1998 *************** *** 196,201 **** --- 196,203 ---- {"block-number", no_argument, NULL, 'R'}, {"block-size", required_argument, NULL, OBSOLETE_BLOCKING_FACTOR}, {"blocking-factor", required_argument, NULL, 'b'}, + {"bzip2", required_argument, NULL, 'y'}, + {"bunzip2", required_argument, NULL, 'y'}, {"catenate", no_argument, NULL, 'A'}, {"checkpoint", no_argument, &checkpoint_option, 1}, {"compare", no_argument, NULL, 'd'}, *************** *** 372,377 **** --- 374,380 ---- PATTERN at list/extract time, a globbing PATTERN\n\ -o, --old-archive, --portability write a V7 format archive\n\ --posix write a POSIX conformant archive\n\ + -y, --bzip2, --bunzip2 filter the archive through bzip2\n\ -z, --gzip, --ungzip filter the archive through gzip\n\ -Z, --compress, --uncompress filter the archive through compress\n\ --use-compress-program=PROG filter through PROG (must accept -d)\n"), *************** *** 448,454 **** Y per-block gzip compression */ #define OPTION_STRING \ ! "-01234567ABC:F:GK:L:MN:OPRST:UV:WX:Zb:cdf:g:hiklmoprstuvwxz" static void set_subcommand_option (enum subcommand subcommand) --- 451,457 ---- Y per-block gzip compression */ #define OPTION_STRING \ ! "-01234567ABC:F:GK:L:MN:OPRST:UV:WX:Zb:cdf:g:hiklmoprstuvwxyz" static void set_subcommand_option (enum subcommand subcommand) *************** *** 805,810 **** --- 808,817 ---- case 'X': exclude_option = 1; add_exclude_file (optarg); + break; + + case 'y': + set_use_compress_program_option ("bzip2"); break; case 'z': </verb> <sect>使用 bzip2 来配合 less <p>马上解压缩 bzip2 档,例如,在不必先 bunzip2 档案的前提下即可用 "less" 到它们身上,你可以做个 lesspipe.sh (man less),像下面: <verb> #!/bin/sh # This is a preprocessor for 'less'. It is used when this environment # variable is set: LESSOPEN="|lesspipe.sh %s" case "$1" in *.tar) tar tvvf $1 2>/dev/null ;; # View contents of various tar'd files *.tgz) tar tzvvf $1 2>/dev/null ;; # This one work for the unmodified version of tar: *.tar.bz2) bzip2 -cd $1 $1 2>/dev/null | tar tzvvf - ;; #This one works with the patched version of tar: # *.tar.bz2) tyvvf $1 2>/dev/null ;; *.tar.gz) tar tzvvf $1 2>/dev/null ;; *.tar.Z) tar tzvvf $1 2>/dev/null ;; *.tar.z) tar tzvvf $1 2>/dev/null ;; *.bz2) bzip2 -dc $1 2>/dev/null ;; # View compressed files correctly *.Z) gzip -dc $1 2>/dev/null ;; *.z) gzip -dc $1 2>/dev/null ;; *.gz) gzip -dc $1 2>/dev/null ;; *.zip) unzip -l $1 2>/dev/null ;; *.1|*.2|*.3|*.4|*.5|*.6|*.7|*.8|*.9|*.n|*.man) FILE=`file -L $1` ; # groff src FILE=`echo $FILE | cut -d ' ' -f 2` if [ "$FILE" = "troff" ]; then groff -s -p -t -e -Tascii -mandoc $1 fi ;; *) cat $1 2>/dev/null ;; # *) FILE=`file -L $1` ; # Check to see if binary, if so -- view with 'strings' # FILE1=`echo $FILE | cut -d ' ' -f 2` # FILE2=`echo $FILE | cut -d ' ' -f 3` # if [ "$FILE1" = "Linux/i386" -o "$FILE2" = "Linux/i386" \ # -o "$FILE1" = "ELF" -o "$FILE2" = "ELF" ]; then # strings $1 # fi ;; esac </verb> <sect>使用 bzip2 来结合 emacs <sect1>为每个人改变 emacs: <p>我写了下面的给 jka-compr.el 用的修补,它会加入 bzip2 成为自动压缩模式。 <p><bf>除外条款:</bf> 我只在 emacs-20.2上试过这个,但是我也找不到有 啥麽理由来相信同样的方法却不能在其他版本上使用的。 <p>使用它, <enum> <item>到 emacs-20.2/lisp 原始程式码目录□ (看你在哪儿 untarred 它的) <item>把下面的修补做成叫 jka-compr.el.diff 的档案(全放在这档案□ )。 <item>然後执行 <tscreen><verb> patch < jka-compr.el.diff </verb></tscreen> <item>启动 emacs,再执行 <tscreen><verb> M-x byte-compile-file jka-compr.el </verb></tscreen> <item>离开 emacs。 <item>把它原来的 jka-compr.elc 放到安全的地方以防有臭虫时备用。 <item>用新的 jka-compr.elc来代替它。 <item>好好玩吧! </enum> <verb> --- jka-compr.el Sat Jul 26 17:02:39 1997 +++ jka-compr.el.new Thu Feb 5 17:44:35 1998 @@ -44,7 +44,7 @@ ;; The variable, jka-compr-compression-info-list can be used to ;; customize jka-compr to work with other compression programs. ;; The default value of this variable allows jka-compr to work with -;; Unix compress and gzip. +;; Unix compress and gzip. David Fetter added bzip2 support :) ;; ;; If you are concerned about the stderr output of gzip and other ;; compression/decompression programs showing up in your buffers, you @@ -121,7 +121,9 @@ ;;; I have this defined so that .Z files are assumed to be in unix -;;; compress format; and .gz files, in gzip format. +;;; compress format; and .gz files, in gzip format, and .bz2 files, +;;; in the snappy new bzip2 format from http://www.muraroa.demon.co.uk. +;;; Keep up the good work, people! (defcustom jka-compr-compression-info-list ;;[regexp ;; compr-message compr-prog compr-args @@ -131,6 +133,10 @@ "compressing" "compress" ("-c") "uncompressing" "uncompress" ("-c") nil t] + ["\\.bz2\\'" + "bzip2ing" "bzip2" ("") + "bunzip2ing" "bzip2" ("-d") + nil t] ["\\.tgz\\'" "zipping" "gzip" ("-c" "-q") "unzipping" "gzip" ("-c" "-q" "-d") </verb> <sect1>为某人改变 emacs: <p> 这次要谢谢 Ulrik Dickow, <url url="mailto:ukdATkampsax.dk" name="ukd@kampsax.dk">,他是Kampsax Technology的系统程式设计师 : 为了让非 sysadmin 的朋友可以自动地使用 bzip2,只需在你的 .emacs 档案□加上下列东东。 <verb> ;; Automatic (un)compression on loading/saving files (gzip(1) and similar) ;; We start it in the off state, so that bzip2(1) support can be added. ;; Code thrown together by Ulrik Dickow for ~/.emacs with Emacs 19.34. ;; Should work with many older and newer Emacsen too. No warranty though. ;; (if (fboundp 'auto-compression-mode) ; Emacs 19.30+ (auto-compression-mode 0) (require 'jka-compr) (toggle-auto-compression 0)) ;; Now add bzip2 support and turn auto compression back on. (add-to-list 'jka-compr-compression-info-list ["\\.bz2\\(~\\|\\.~[0-9]+~\\)?\\'" "zipping" "bzip2" () "unzipping" "bzip2" ("-d") nil t]) (toggle-auto-compression 1 t) </verb> <sect>用 bzip2 来配合 wu-ftpd <p> 感谢 Arnaud Launay 这则节省频宽的秘诀。下面的内容应该是放到 /etc/ftpconversions □面来达成以 bzip2 来做即时压缩及解压缩 。请确认路径 (像 /bin/compress) 要正确。 <verb> :.Z: : :/bin/compress -d -c %s:T_REG|T_ASCII:O_UNCOMPRESS:UNCOMPRESS : : :.Z:/bin/compress -c %s:T_REG:O_COMPRESS:COMPRESS :.gz: : :/bin/gzip -cd %s:T_REG|T_ASCII:O_UNCOMPRESS:GUNZIP : : :.gz:/bin/gzip -9 -c %s:T_REG:O_COMPRESS:GZIP :.bz2: : :/bin/bzip2 -cd %s:T_REG|T_ASCII:O_UNCOMPRESS:BUNZIP2 : : :.bz2:/bin/bzip2 -9 -c %s:T_REG:O_COMPRESS:BZIP2 : : :.tar:/bin/tar -c -f - %s:T_REG|T_DIR:O_TAR:TAR : : :.tar.Z:/bin/tar -c -Z -f - %s:T_REG|T_DIR:O_COMPRESS|O_TAR:TAR+COMPRESS : : :.tar.gz:/bin/tar -c -z -f - %s:T_REG|T_DIR:O_COMPRESS|O_TAR:TAR+GZIP : : :.tar.bz2:/bin/tar -c -y -f - %s:T_REG|T_DIR:O_COMPRESS|O_TAR:TAR+BZIP2 </verb> <sect>使用 bzip2 来配合 grep <p>下面的公用程式,我管它叫 bgrep,事实上是把伴随在 Linux 的 zgrep 做个小更改 而已。你可以使用它来 grep,而不需先 bunzip2 档案。 <verb> #!/bin/sh # bgrep -- a wrapper around a grep program that decompresses files as needed PATH="/usr/bin:$PATH"; export PATH prog=`echo $0 | sed 's|.*/||'` case "$prog" in *egrep) grep=${EGREP-egrep} ;; *fgrep) grep=${FGREP-fgrep} ;; *) grep=${GREP-grep} ;; esac pat="" while test $# -ne 0; do case "$1" in -e | -f) opt="$opt $1"; shift; pat="$1" if test "$grep" = grep; then # grep is buggy with -e on SVR4 grep=egrep fi;; -*) opt="$opt $1";; *) if test -z "$pat"; then pat="$1" else break; fi;; esac shift done if test -z "$pat"; then echo "grep through bzip2 files" echo "usage: $prog [grep_options] pattern [files]" exit 1 fi list=0 silent=0 op=`echo "$opt" | sed -e 's/ //g' -e 's/-//g'` case "$op" in *l*) list=1 esac case "$op" in *h*) silent=1 esac if test $# -eq 0; then bzip2 -cd | $grep $opt "$pat" exit $? fi res=0 for i do if test $list -eq 1; then bzip2 -cdfq "$i" | $grep $opt "$pat" > /dev/null && echo $i r=$? elif test $# -eq 1 -o $silent -eq 1; then bzip2 -cd "$i" | $grep $opt "$pat" r=$? else bzip2 -cd "$i" | $grep $opt "$pat" | sed "s|^|${i}:|" r=$? fi test "$r" -ne 0 && res="$r" done exit $res </verb> <sect>bzip2 配合 X 下的 Netscape 来使用。 <p> tenthumbs@cybernex.net 说: <tscreen> 我找到一个可以让 Linux Netscape 来使用 bzip2 做为 Content-Encoding 就如同它使用 gzip 一样。把下面的东东加到 $HOME/.Xdefaults 或是 $HOME/.Xresources <p> 我使用 -s 选项,是因为选择放弃解压缩的速度来换得 RAM 的占用。 你可以把它设成你自己要的。 </tscreen> <verb> Netscape*encodingFilters: \ x-compress : : .Z : uncompress -c \n\ compress : : .Z : uncompress -c \n\ x-gzip : : .z,.gz : gzip -cdq \n\ gzip : : .z,.gz : gzip -cdq \n\ x-bzip2 : : .bz2 : bzip2 -ds \n </verb> <sect>使用 bzip2 来再压缩其他的压缩格式 <p>下面的 perl 程式会把以下列的压缩格式档 (.tar.gz, .tgz. .tar.Z, 和 .Z for this iteration) 重新打包成最佳的压缩值。这 perl 原始程式都有全方位的好文件 来说明它做什麽以及它如何办到的。 <verb> #!/usr/bin/perl -w ####################################################### # # # This program takes compressed and gzipped programs # # in the current directory and turns them into bzip2 # # format. It handles the .tgz extension in a # # reasonable way, producing a .tar.bz2 file. # # # ####################################################### $counter = 0; $saved_bytes = 0; $totals_file = '/tmp/machine_bzip2_total'; $machine_bzip2_total = 0; while(<*[Zz]>) { next if /^bzip2-0.1pl2.tar.gz$/; push @files, $_; } $total = scalar(@files); foreach (@files) { if (/tgz$/) { ($new=$_) =~ s/tgz$/tar.bz2/; } else { ($new=$_) =~ s/\.g?z$/.bz2/i; } $orig_size = (stat $_)[7]; ++$counter; print "Repacking $_ ($counter/$total)...\n"; if ((system "gzip -cd $_ |bzip2 >$new") == 0) { $new_size = (stat $new)[7]; $factor = int(100*$new_size/$orig_size+.5); $saved_bytes += $orig_size-$new_size; print "$new is about $factor% of the size of $_. :",($factor<100)?')':'(',"\n"; unlink $_; } else { print "Arrgghh! Something happened to $_: $!\n"; } } print "You've ", ($saved_bytes>=0)?"saved":"lost", " $saved_bytes bytes of storage space :", ($saved_bytes>=0)?")":"(", "\n"; unless (-e '/tmp/machine_bzip2_total') { system ('echo "0" >/tmp/machine_bzip2_total'); system ('chmod', '0666', '/tmp/machine_bzip2_total'); } chomp($machine_bzip2_total = `cat $totals_file`); open TOTAL, ">$totals_file" or die "Can't open system-wide total: $!"; $machine_bzip2_total += $saved_bytes; print TOTAL $machine_bzip2_total; close TOTAL; print "That's a machine-wide total of ",`cat $totals_file`," bytes saved.\n"; </verb> <sect>中译本 <p>译者注: 若您发现本文件内容有翻译不顺畅或错误的地方,请您来信告诉我,以做更正,谢谢。 译者电子邮件 <tt><htmlurl url="mailto:linuxer.bbs@cis.nctu.edu.tw" name="linuxer.bbs@cis.nctu.edu.tw"></tt> 或<htmlurl url="mailto:linux4tw@geocities.com" name="linux4tw@geocities.com"> <P> 译注:这份 HOWTO 文件的中文版可在台湾 Linux 使用者组织下的中文 Linux 文件计画<url url="http://www.linux.org.tw/CLDP/"><newline> 或是"Linux for Taiwan 台湾人的 Linux "<htmlurl url="http://members.xoom.com/linux4tw/" name="http://members.xoom.com/linux4tw/"> 下取得。 </article>