cpio VS tar и cp

Току-що научих, че cpio има три режима: копиране навън, копиране в и преминаване.

Чудех се какви са предимствата и недостатъците на cpio в режими на копиране и копиране в сравнение с tar. Кога е по-добре да използвате cpio и кога да използвате tar?

Подобен въпрос за cpio в режим на преминаване спрямо cp.

Благодаря и поздрави!


person Tim    schedule 03.06.2010    source източник
comment
Това по-подходящо ли е за serverfault.com?   -  person Stefan Lasiewski    schedule 03.06.2010
comment
Повторно публикувано тук: serverfault.com/questions/148747   -  person Tom Zych    schedule 15.10.2014
comment
свързани: superuser.com/questions /343915/   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 13.02.2018


Отговори (3)


Не виждам причина да използвам cpio по друга причина, освен извличане на отворени RPM файлове, чрез disrpm или rpm2cpio, но може да има крайни случаи, в които cpio е за предпочитане пред катран.

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

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

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

Tar е по-универсално известен, стана по-гъвкав през годините и е по-вероятно да се поддържа в дадена система. Въпреки това Cpio все още се използва в няколко области, като например формата Red Hat package (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)

Режими

Копиране: Това е за създаване на архив, подобно на tar -pc

Копиране: Това е за извличане на архив, подобно на tar -px

Преминаване: Това е основно и двете от горните, подобно на tar -pc … |tar -px, но в една команда (и следователно микроскопично по-бързо). Подобен е на cp -pdr, въпреки че и cpio, и (особено) tar имат повече възможности за персонализиране. Също така помислете за rsync -a, което хората често забравят, тъй като по-често се използва през мрежова връзка.

Не съм сравнявал тяхната производителност, но очаквам, че ще бъдат доста сходни по отношение на процесора, паметта и размера на архива (след компресиране).

person Adam Katz    schedule 07.07.2016
comment
Какво имате предвид под извличане на отворени RPM файлове? Второ, защо някой би искал да изпълни командата tar -pc file.tar file | tar -px file.tar? Каква цел служи? - person Motivated; 25.01.2019
comment
@Motivated – CPIO е контейнерът, използван от RPM; вижте инструментите, които свързах по-горе, или това ръководство на Как да извлечете RPM пакет, без да го инсталирате. Прехвърлянето на tar в себе си, подобно на пропускателния режим на CPIO, е добро за запазване на неща като връзки и разрешения, но също така помислете за tar -pzc my_dir |ssh otherserver tar -pzx за копиране на директория между местоположения без действителен tarball (да кажем, че нямате място в първата система). И за двете rsync -a е за предпочитане, макар и малко по-трудно за използване. - person Adam Katz; 25.01.2019
comment
Благодаря. Имате предвид, че „извличането на отворени RPM файлове предполага извличане на RPM пакет без инсталирането му? Ако да, защо човек би го направил? Не разбирам стойността на прехвърлянето на tar към себе си, ако погледна командата tar -pzc my_dir | ssh someserver tar -pzx? Първата команда не създава ли tar архив, който е компресиран и впоследствие го разопакова? - person Motivated; 25.01.2019
comment
Понякога просто искате да видите какво има вътре в пакет, напр. кажете, че искате да вземете изображение или шрифт, но не искате да инсталирате пакета. Ако не виждате полза от прехвърлянето на tar в себе си през мрежа, без да правите временен файл за първоначално копиране в мрежа, тогава не мога да го обясня тук, освен да кажа, че е значително по-добър от scp -pr. - person Adam Katz; 25.01.2019
comment
Използването на стойност вероятно не беше точната дума. Исках да кажа, че не разбирам случаите на употреба, в които човек би превел tar към себе си. Например, когато казвате временен файл, искате ли да кажете, че той е компресиран до степен да прехвърли файла и некомпресиран, след като бъде ангажиран? Ще се радвам да разбера различните сценарии. - person Motivated; 26.01.2019
comment
@Motivated – Без изпращане на tar към себе си: (1) създаване на архив с локално съдържание, (2) копиране на архив във втора система, (3) извличане на архив на втора система, (4) изтриване на архив на двете системи. Ами ако локалната система няма свободно място в нея? С вливане на катран в себе си, няма архив; данните от първата tar команда се изпращат директно през мрежата към втората система. - person Adam Katz; 27.01.2019
comment
Не знаех, че tar може да предава поточно данни. Имате предвид, че командата `tar -pzc file.tar file | ssh someserver tar -pzx file.tar не създава временен tar файл? Архивира ли, компресира, предава поточно, декомпресира, изтрива? - person Motivated; 27.01.2019
comment
@Motivated – Да. - person Adam Katz; 27.01.2019

TAR(1) е също толкова добър, колкото cpio(), ако не и по-добър. Може да се твърди, че всъщност е по-добър от CPIO, защото е повсеместен и проверен. Трябва да има причина да имаме катранени топчета навсякъде.

person Ernest Montrose    schedule 04.01.2016

Защо 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 в обратни кавички; дължината на командния ред ще бъде превишена; трябва да използвате междинен файл. Отделните команди за намиране и 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
    

    Отново, някои бележки: Отделните команди за намиране и 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 чете в изходното дърво и записва в целевото дърво един файл наведнъж. Ако имате многопроцесорна машина (по това време използвах 16 процесора на машина), паралелното писане стана много важно. Ускорих копирането на 8GB дърво до 30 минути; това е 4.6MB/sec! Разбира се, звучи бавно, тъй като 100Mbit мрежа може лесно да направи 5-10MB/sec, но това е времето за създаване на inode, което го прави бавно; лесно имаше 500 000 файла в това дърво. Така че, ако създаването на inode е тясното място, тогава трябваше да паралелизирам тази операция. За сравнение копирането на файловете по еднопоточен начин ще отнеме 4 часа. Това е 8 пъти по-бързо!

    Втора причина, поради която това беше по-бързо, е, че паралелните tcp канали са по-малко уязвими от изгубен пакет тук и там. Ако една тръба спре поради изгубен пакет, останалите обикновено няма да бъдат засегнати. Не съм много сигурен доколко това направи разликата, но за фини многонишкови ядра, това отново може да бъде по-ефективно, тъй като натоварването може да се разпредели между всички тези неактивни процесори

Според моя опит cpio върши като цяло по-добра работа от tar, както и е по-преносим аргумент (аргументите не се променят между версиите на cpio!), въпреки че може да не се намери на някои системи (не е инсталиран по подразбиране на RedHat) , но отново Solaris също не идва с gzip по подразбиране.

person Bubli Sagar    schedule 27.11.2010
comment
-1 за безсрамно копиране и поставяне без правилно препращане. - person C2H5OH; 28.01.2013
comment
Някои от твърденията също са неискрени, тъй като tar може да прочете своя списък с файлове от канал, при условие че знаете малко за вашата обвивка. - person Ben Voigt; 14.05.2013
comment
Не само това, куп примери с tar дори няма да работят. - person Ben Voigt; 14.05.2013
comment
Оригиналният url вече е 404, така че може би безсрамното копиране/поставяне вече е ценен архив :) - person Guillaume; 31.05.2017
comment
Ето по-подходяща и по-директна версия на този изходен материал както е запазено от Wayback Machine на archive.org - person Adam Katz; 29.08.2017