cpio VS tar和cp

时间:2010-06-03 13:33:17

标签: bash archive tar cp

我刚刚了解到cpio有三种模式:copy-out,copy-in和pass-through。

我想知道cpio在tar下的copy-out和copy-in模式下有什么优缺点。何时使用cpio以及何时使用tar?

在传递模式下与cp。相似的问题。

谢谢和问候!

3 个答案:

答案 0 :(得分:3)

除了通过disrpmrpm2cpio翻录已打开的RPM文件之外,我认为没有理由使用cpio,但可能存在cpio优于tar的极端情况。

历史和人气

tarcpio都是竞争档案格式,于1979年在Version 7 Unix中引入,然后包含在POSIX。1-1988中,尽管只留下了焦油下一个标准,POSIX.1-2001 1

Cpio的文件格式已多次更改,并且版本之间尚未完全兼容。例如,现在存在二进制文件信息数据的ASCII编码表示。

Tar更为人所知,多年来变得更加通用,并且更有可能在特定系统上得到支持。 Cpio仍然在一些领域使用,例如Red Hat package格式(RPM),尽管RPM v5(这无疑是模糊的)使用xar而不是cpio。

虽然tar更常见,但它们都存在于大多数类Unix系统上。以下是Debian's install stats

#rank  name    inst    vote    old  recent  no-files  (maintainer)
   13   tar  189206  172133   3707   13298        68  (Bdale Garbee)
   61  cpio  189028   71664  96346   20920        98  (Anibal Monsalve Salazar)

模式

副本:这是用于创建档案,类似于tar -pc

复制:这适用于档案提取,类似于tar -px

传递:这基本上都是上述两种,类似于tar -pc … |tar -px但是在一个命令中(因此在显微镜下更快)。它与cp -pdr类似,但cpio和(特别是)tar都具有更多的可定制性。还要考虑rsync -a,人们经常会忘记,因为它通常用于网络连接。

我没有比较它们的性能,但我预计它们在CPU,内存和存档大小方面会非常相似(压缩后)。

答案 1 :(得分:-1)

如果没有更好的话,TAR(1)和cpio()一样好。事实上,人们可以说它比CPIO更好,因为它无处不在并经过审查。这就是为什么我们到处都有焦油球的原因。

答案 2 :(得分:-5)

为什么cpio比tar更好?有很多原因。

  1. cpio保留硬链接,如果您将其用于备份,这很重要。
  2. cpio没有恼人的文件名长度限制。当然,gnutar有一个“hack”允许你使用更长的文件名(它创建一个临时文件,它存储真实姓名),但它本身不能移植到非gnu tar。
  3. 默认情况下,cpio会保留时间戳
  4. 编写脚本时,它可以更好地控制哪些文件被复制,哪些文件不被复制,因为您必须明确列出要复制的文件。例如,以下哪项更容易阅读和理解?

    find . -type f -name '*.sh' -print | cpio -o | gzip >sh.cpio.gz
    

    或在Solaris上:

    find . -type f -name '*.sh' -print >/tmp/includeme
    tar -cf - . -I /tmp/includeme | gzip >sh.tar.gz
    

    或与gnutar:

    find . -type f -name '*.sh' -print >/tmp/includeme
    tar -cf - . --files-from=/tmp/includeme | gzip >sh.tar.gz
    

    这里有几个具体的注释:对于大型文件列表,你不能把find放在反向引号中;命令行长度将超限;你必须使用中间文件。由于操作是连续完成的,因此单独的find和tar命令固有地较慢。

    考虑这种更复杂的情况,你想要一棵树完全打包,但是一些文件放在一个tar中,剩下的文件放在另一个tar中。

    find . -depth -print >/tmp/files
    egrep    '\.sh$' /tmp/files | cpio -o | gzip >with.cpio.gz
    egrep -v '\.sh$' /tmp/files | cpio -o | gzip >without.cpio.gz
    

    或在Solaris下:

    find . -depth -print >/tmp/files
    egrep    '\.sh$' /tmp/files >/tmp/with
    tar -cf - . -I /tmp/with    | gzip >with.tar.gz
    tar -cf - .    /tmp/without | gzip >without.tar.gz
    ##          ^^-- no there's no missing argument here.  It's just empty that way
    

    或与gnutar:

    find . -depth -print >/tmp/files
    egrep    '\.sh$' /tmp/files >/tmp/with
    tar -cf - . -I /tmp/with    | gzip >with.tar.gz
    tar -cf - . -X /tmp/without | gzip >without.tar.gz
    

    同样,一些注意事项:单独的find和tar命令本质上较慢。创建更多中间文件会产生更多混乱。 gnutar感觉有点干净,但命令行选项本质上是不兼容的!

  5. 如果您需要在繁忙的网络中快速将大量文件从一台计算机复制到另一台计算机,则可以并行运行多个cpio。例如:

    find . -depth -print >/tmp/files
    split /tmp/files
    for F in /tmp/files?? ; do
      cat $F | cpio -o | ssh destination "cd /target && cpio -idum" &
    done
    

    请注意,如果您可以将输入拆分为均匀大小的部分,这将有所帮助。我创建了一个名为'npipe'的实用程序来执行此操作。 npipe将从stdin中读取行,并创建N个输出管道,并在每行消耗时将行提供给它们。这样,如果第一个条目是一个需要10分钟传输的大文件,其余的是需要2分钟传输的小文件,那么等待大文件加上在其后面排队的另外十几个小文件就不会停滞不前。这样,您最终会按需求进行拆分,而不是严格按文件列表中的行数或字节数进行拆分。使用gnu-xargs的并行分叉功能可以实现类似的功能,除了将参数放在命令行而不是将它们流式传输到stdin。

    find . -depth -print >/tmp/files
    npipe -4 /tmp/files 'cpio -o | ssh destination "cd /target && cpio -idum"'
    

    这怎么更快?为什么不使用NFS?为什么不使用rsync? NFS本质上非常慢,但更重要的是,任何单个工具的使用本质上都是单线程的。 rsync在源树中读取并一次向目标树写入一个文件。如果你有一台多处理器机器(当时我每台机器使用16cpu),并行写入变得非常重要。我把8GB树的副本加速到30分钟;这是4.6MB /秒!当然它听起来很慢,因为100Mbit网络可以很容易地做到5-10MB /秒,但是它的节点创建时间使它变慢;这棵树上有500,000个文件。因此,如果inode创建是瓶颈,那么我需要并行化该操作。相比之下,以单线程方式复制文件需要4个小时。这快8倍!

    这个更快的第二个原因是并行tcp管道不太容易受到丢包的影响。如果一个管道由于丢失数据包而停滞,其他管道通常不会受到影响。我不确定这有多大差别,但对于精细的多线程内核,这可以再次提高效率,因为工作负载可以分布在所有那些空闲的cpu上

  6. 根据我的经验,cpio总体上比tar更好,并且更多的参数可移植(参数在cpio版本之间不会改变!),尽管在某些系统上可能找不到(默认情况下不安装)在RedHat上),但是Solaris也没有默认配备gzip。