cpio VS tar и cp - PullRequest
       41

cpio VS tar и cp

13 голосов
/ 03 июня 2010

Я только что узнал, что в cpio есть три режима: копирование, копирование и пропуск.

Мне было интересно, каковы преимущества и недостатки cpio в режимах копирования и копирования по сравнению с tar. Когда лучше использовать cpio, а когда использовать tar?

Аналогичный вопрос для cpio в режиме сквозного доступа по сравнению с cp.

Спасибо и всего наилучшего!

Ответы [ 3 ]

3 голосов
/ 07 июля 2016

Я не вижу причин использовать cpio по любой другой причине, кроме копирования открытых RPM-файлов, через disrpm или rpm2cpio , но могут быть угловые случаи, когда cpio предпочтительнее tar .

История и популярность

Оба tar и cpio являются конкурирующими форматами архивов, которые были введены в Версия 7 Unix в 1979 году и затем включены в POSIX . 1-1988, хотя в следующем стандарте осталась только смола, POSIX.1-2001 1 .

Формат файла Cpio менялся несколько раз и не оставался полностью совместимым между версиями. Например, теперь существует ASCII-кодированное представление данных двоичного файла.

Тар известен более широко, с годами стал более универсальным и с большей вероятностью будет поддерживаться в данной системе. Cpio все еще используется в некоторых областях, таких как формат пакета Red Hat (RPM), хотя RPM v5 (который, по общему признанию, неясен) использует вместо этого xar cpio.

Оба работают на большинстве Unix-подобных систем, хотя tar более распространен. Вот Статистика установки Debian :

#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)

Режимы

Copy-out : Это для создания архива, сродни tar -pc

Копирование : Это для извлечения архива, сродни tar -px

Pass-through : Это в основном оба из вышеперечисленных, сродни tar -pc … |tar -px, но в одной команде (и, следовательно, микроскопически быстрее). Это похоже на cp -pdr, хотя и cpio, и (особенно) tar имеют больше возможностей для настройки. Также рассмотрим rsync -a, о котором люди часто забывают, так как он чаще используется по сетевому соединению.

Я не сравнивал их производительность, но ожидаю, что они будут очень похожи по процессору, памяти и размеру архива (после сжатия).

0 голосов
/ 04 января 2016

TAR (1) так же хорош, как cpio (), если не лучше. Можно утверждать, что это на самом деле лучше, чем CPIO, потому что он вездесущ и проверен. Должна быть причина, по которой у нас везде есть смоляные шарики.

0 голосов
/ 27 ноября 2010

Почему cpio лучше, чем tar? Ряд причин.

  1. cpio сохраняет жесткие ссылки, что важно, если вы используете его для резервного копирования.
  2. У cpio нет такого раздражающего ограничения длины имени файла. Конечно, у gnutar есть «хак», который позволяет вам использовать более длинные имена файлов (он создает временный файл, в котором хранится настоящее имя), но по своей сути он не переносим для не-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
    

    или с гнутаром:

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

    Пара конкретных замечаний: для больших списков файлов вы не можете найти find в обратных кавычках; длина командной строки будет превышена; Вы должны использовать промежуточный файл. Отдельные команды find и 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
    

    или с гнутаром:

    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, за исключением того, что они помещают аргументы в командную строку вместо потоковой передачи их на стандартный ввод.

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

    Как это быстрее? Почему бы не использовать NFS? Почему бы не использовать rsync? NFS по своей сути очень медленный, но, что более важно, использование любого отдельного инструмента по своей сути однопоточное. rsync читает в исходном дереве и записывает в дерево назначения по одному файлу за раз. Если у вас есть многопроцессорная машина (в то время, когда я использовал 16 процессоров на машину), параллельная запись стала очень важной. Я ускорил копию дерева 8 ГБ до 30 минут; это 4,6 МБ / с! Конечно, это звучит медленно, поскольку 100-мегабитная сеть может легко обрабатывать 5-10 МБ / с, но это время создания инода делает его медленным; в этом дереве было легко 500 000 файлов. Так что, если создание инода является узким местом, то мне нужно было распараллелить эту операцию. Для сравнения, копирование файлов однопоточным способом заняло бы 4 часа. Это в 8 раз быстрее!

    Вторичная причина того, что это было быстрее, заключается в том, что параллельные TCP-каналы менее уязвимы для потерянного пакета здесь и там. Если один канал зависает из-за потерянного пакета, другие не будут затронуты. Я не совсем уверен, насколько это изменило ситуацию, но для многопоточных ядер это может быть еще более эффективным, поскольку рабочая нагрузка может быть распределена по всем этим простаивающим процессорам

По моему опыту, cpio делает в целом лучшую работу, чем tar, а также является более переносимым аргументом (аргументы не меняются между версиями cpio!), Хотя он может не быть найден в некоторых системах (по умолчанию не установлен) в RedHat), но опять же Solaris также не поставляется с gzip по умолчанию.

...