电脑技术学习

Bzip2 Howto

dn001
作者: David Fetter, dfetter@best.com
译者:谢昆中 HSIEH KUN-CHUNG, (电子邮件 linuxer.bbs@cis.nctu.edu.tw 或 linux4tw@geocities.com 网页 "Linux for Taiwan 台湾人的 Linux" http://members.xoom.com/linux4tw/

版本 v1.92,1998年 8月18日 


--------------------------------------------------------------------------------
这份文件在教你如何使用新的 bzip2 压缩程式。目前的 sgml 版本被放在 EURO 这□,还有 "作者用的" sgml 档放在 http://www.best.com/~dfetter/Bzip2-HOWTO/Bzip2-HOWTO.sgml。 
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

1. 简介
Bzip2 是个很棒的压缩资料用之新型演算法。大致上能够达到以它的对手 gzip 所产出的档案之 60-70% 左右的压缩率。 


这份文件将教你几个 bzip2 的应用软体。 


本文件的未来版将会讨论即将出现的 bzip2 程式库,该程式库原bzip2 的作者 Julian Seward 描述如下: 


现在正致力於 bzip2 的下一个版本,它也将采用相同的 .bz2 档案格式;
主要增加的功能是一个像 zlib 的程式库。让我们可以从程式□头来读取和书写资料到这种格式的档案□。


本文件的未来版本也会包含是否应该 (以及如何)让 Linux kernel 使用 bzip2之议题的结论。 


1.1 沿革历史 
v1.92更新 取得 bzip2 二进位程式码 章节,加入 S.u.S.E.的。
v1.91
在 使用 bzip2 配合 tar 那章□修正一个□例以及弄清楚一些 shell 句子。感谢 Alessandro Rubini。 


更新 buzzit 工具不会去 stomp 原来的 bzip2 压缩档。 


新增 bgrep, 像 zgrep-的工具。 


v1.9
澄清 gcc 2.7.* 的问题。感谢 Ulrik Dickow 的热心指出。 


加入 Leonard Jean-Marc 很棒的配合 tar 


加上 Linus 攀erlund 的瑞典文版本。 


依照 Arnaud Launay 的建议修正了 wu-ftpd 章节 


把译文放到它们自己的位章节上。 


v1.8
把 buzzit 和 tar.diff 放到 sgml 文件□它们应该被放置的地方。修正拼字与格式。感谢 Arnaud Launay 的协助我修正这份文件。:-) 


杀掉 xv 计画,因此大家不感兴趣。 


加上 teasers 为本文件的未来版本。 


v1.7 
加入 buzzit 公用程式。修正对 gnu tar 的修补。 


v1.6 
加入 TenThumbs 的 Netscape 致能者。 


以及依据它的建议更改 lesspipe.sh 。它现在可以工作的更好了。 


v1.5 
加入 Arnaud Launay 的法文译本,以及他的 wu-ftpd 档。 


v1.4 
加入 Tetsu Isaji 的日文译本。 


v1.3 
加入 Ulrik Dickow 给 19.30 或更高版本用的 .emacs 档□


(还有修正给 emacs用的 jka-compr.el 修补档。糟了! Bzip2 还没有(?) "append" 的旗标选项。) 


v1.2 
加入对 emacs 的修补,让它可以自动地办识出 .bz2 档。 


v1.1 
加入对 emacs 


v1.0 
第一回合。 




--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

2. 取得 bzip2
Bzip2 的主网页在 英国的主网站http://www.muraroa.demon.co.uk/。美国的映射站在 这http://www.digistar.com/bzip2/index.html。你也可以在 Red Hat 的ftp 站□ ftp://ftp.redhat.com/pub/contrib。 


2.1 Bzip2-HOWTO 各种语言版本 
说法语的人可以看看 Arnaud Launay 的法文文件。网页版本在 这□http://www.freenix.fr/linux/HOWTO/mini/Bzip2.html,你可以用 ftp 来取得ftp://ftp.lip6.fr/pub/linux/french/docs/HOWTO/mini/Bzip2.gz 你可以用 电子邮件来连络Arnaud 


说日语的人可以看看 Tetsu Isaji的 日文译本。你可以用上Isaji的 网站,或是用 电子邮件的方式。 



说瑞典语的朋友可以参阅 Linus 攀erlund 的瑞典文译本 按这。你可以用 电子邮件 与 Linus 连络。 


2.2 取得 bzip2 未编译的二进位档 
查一下主网站。 


Debian 的Intel 二进位程式码在 这□ftp://ftp.debian.org/debian/dists/stable/main/binary-i386/utils/bzip2_0.1pl2-5.deb。 


Red Hat的 alpha 二进位程式码在 这□ftp://ftp.redhat.com/pub/redhat/redhat-5.1/alpha/RedHat/RPMS/bzip2-0.1pl2-1.alpha.rpm。 


Red Hat的 Intel 二进位程式码在 这□ftp://ftp.redhat.com/pub/redhat/redhat-5.1/i386/RedHat/RPMS/bzip2-0.1pl2-1.i386.rpm。 


Red Hat的 SPARC 二进位程式码在 这□ftp://ftp.redhat.com/pub/redhat/redhat-5.1/sparc/RedHat/RPMS/bzip2-0.1pl2-1.sparc.rpm。 


Slackware的 Intel 二进位程式码在 这□ftp://www.cdrom.com/pub/linux/slackware-3.5/slakware/a1/bzip2.tgz。 


S.u.S.E.的 Intel 二进位程式码在 这□ftp://ftp.suse.com/pub/SuSE-Linux/5.2/suse/ap1/bzip.rpm。 

你也可以从许多相类似的映射站得取得档案。 


2.3 取得 bzip2 原始程式 
你可以从官方的网站 (看 Getting Bzip2 ,或是 Red Hat 也有 它ftp://ftp.redhat.com/pub/contrib/SRPMS/bzip2-0.1pl2-1.src.rpm)。 


2.4 编译 bzip2 给你的机器使用 
如果你有 gcc 2.7.*,将下面这行 

CFLAGS = -O3 -fomit-frame-pointer -funroll-loops

改成 

CFLAGS = -O2 -fomit-frame-pointer

也就是,把 -O2 改成 -O3 并把 -funroll-loops删掉。你也可以加入任何你在编译 kernel 时的 -m* 旗标 (例如像 -m486)。 

避免使用 -funroll-loops 是最重要的了,因为它会造成许多的 gcc 2.7产生错误的程式码,以及全部的 gcc 2.7 产生速度慢又较胖的程式码。对其他的编译器 (lcc, egcs, gcc 2.8.x) 使用内定的 CFLAGS 就没问题。 

之後,只需 make 它,然後依照 README 来安装它。 



--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

3. 使用 bzip2
请参阅很棒的手册 :) 



--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

4. 配合 tar来使用 bzip2
下面有三种配合 tar 使用 bzip2 的方法,也就是 

4.1 容易设立: 
这个方法跟本就不必做设定。执行解开bzip2'd 的 tar包裹,在现行目录底下有个 foo.tar.bz2,执行 

/path/to/bzip2 -cd foo.tar.bz2 | tar xf -

成功了,但可能有常需输入的小缺点。 


4.2 容易设立,容易使用,不需要 root 的特权: 
感谢 Leonard Jean-Marc 贡献这个小技巧。也谢谢 Alessandro Rubini 从 csh□分类出 bash 的。 


在你的 .bashrc□,你可以加入像下面这行: 

alias btar='tar --use-compress-program /usr/local/bin/bzip2 '


在你的 .tcshrc 或 .cshrc□,可用下面这行相同的: 

alias btar 'tar --use-compress-program /usr/local/bin/bzip2'


4.3 同样是容易使用,但需要 root 来存取。 
用下面来方法来修补 gnu tar 1.12: 

cd tar-1.12/src; patch < /path/to/tar.diff

编译、安装它,你已准备就绪了。用"which tar" 和 "which bzip2"来确认这两个 tar 和 bzip2 有在你的 $PATH □。要使用新的 tar,只需 
 tar xyf foo.tar.bz2

来压缩档案。 
要制作新的压缩档,同样地: 

 tar cyf foo.tar.bz2 档名1 档名2 档名3...目录1 目录2...

下面是修补的地方: 

*** 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 PATTERNn
    -o, --old-archive, --portability   write a V7 format archiven
        --posix                        write a POSIX conformant archiven
+   -y, --bzip2, --bunzip2             filter the archive through bzip2n
    -z, --gzip, --ungzip               filter the archive through gzipn
    -Z, --compress, --uncompress       filter the archive through compressn
        --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':



--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

5. 使用 bzip2 来配合 less
马上解压缩 bzip2 档,例如,在不必先 bunzip2 档案的前提下即可用 "less" 到它们身上,你可以做个 lesspipe.sh (man less),像下面: 

#!/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



--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

6. 使用 bzip2 来结合 emacs
6.1 为每个人改变 emacs: 
我写了下面的给 jka-compr.el 用的修补,它会加入 bzip2 成为自动压缩模式。 

除外条款: 我只在 emacs-20.2上试过这个,但是我也找不到有啥麽理由来相信同样的方法却不能在其他版本上使用的。 

使用它, 

到 emacs-20.2/lisp 原始程式码目录□ (看你在哪儿 untarred 它的) 
把下面的修补做成叫 jka-compr.el.diff 的档案(全放在这档案□ )。 
然後执行 
 patch < jka-compr.el.diff

启动 emacs,再执行 
 M-x byte-compile-file jka-compr.el

离开 emacs。 
把它原来的 jka-compr.elc 放到安全的地方以防有臭虫时备用。 
用新的 jka-compr.elc来代替它。 
好好玩吧! 
--- 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")


6.2 为某人改变 emacs: 
这次要谢谢 Ulrik Dickow, ukd@kampsax.dk,他是Kampsax Technology的系统程式设计师 : 

为了让非 sysadmin 的朋友可以自动地使用 bzip2,只需在你的 .emacs 档案□加上下列东东。 


 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)



--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

7. 用 bzip2 来配合 wu-ftpd
感谢 Arnaud Launay 这则节省频宽的秘诀。下面的内容应该是放到 /etc/ftpconversions □面来达成以 bzip2 来做即时压缩及解压缩。请确认路径 (像 /bin/compress) 要正确。 


 :.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



--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

8. 使用 bzip2 来配合 grep
下面的公用程式,我管它叫 bgrep,事实上是把伴随在 Linux 的 zgrep 做个小更改而已。你可以使用它来 grep,而不需先 bunzip2 档案。 


#!/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



--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

9. bzip2 配合 X 下的 Netscape 来使用。
tenthumbs@cybernex.net 说: 


我找到一个可以让 Linux Netscape 来使用 bzip2 做为 Content-Encoding 就如同它使用 gzip 一样。把下面的东东加到 $HOME/.Xdefaults 或是 $HOME/.Xresources 
我使用 -s 选项,是因为选择放弃解压缩的速度来换得 RAM 的占用。你可以把它设成你自己要的。 


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



--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

10. 使用 bzip2 来再压缩其他的压缩格式
下面的 perl 程式会把以下列的压缩格式档 (.tar.gz, .tgz. .tar.Z, 和 .Z for this iteration) 重新打包成最佳的压缩值。这 perl 原始程式都有全方位的好文件来说明它做什麽以及它如何办到的。 

#!/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";



--------------------------------------------------------------------------------

--------------------------------------------------------------------------------

11. 中译本
译者注: 若您发现本文件内容有翻译不顺畅或错误的地方,请您来信告诉我,以做更正,谢谢。译者电子邮件 linuxer.bbs@cis.nctu.edu.tw 或 linux4tw@geocities.com

译注:这份 HOWTO 文件的中文版可在台湾 Linux 使用者组织下的中文 Linux 文件计画 http://www.linux.org.tw/CLDP/
或是"Linux for Taiwan 台湾人的 Linux " http://members.xoom.com/linux4tw/ 下取得。 


--------------------------------------------------------------------------------

标签: