CP против кошки, чтобы скопировать файл

12

cp a bи cat a > bкакая разница?

В x86 установочном скрипте дерева исходного кода ядра Linux ( arch/x86/boot/install.sh) используются оба:

cat $2 > $4/vmlinuz
cp $3 $4/System.map

Почему они просто не сохраняют один и тот же формат, если один лучше другого?

Цянь
источник

Ответы:

15

Еще одна проблема приходит мне на ум, где catvs. cpимеет существенное значение:

По определению, cat будет расширять разреженные файлы, заполняя промежутки «реальными» нулевыми байтами, в то время как cp по крайней мере можно сказать, чтобы сохранить дыры.

Разреженные файлы - это файлы, в которых последовательности нулевых байтов были заменены метаданными для экономии места. Вы можете протестировать, создав один с dd, и продублировать его с помощью инструментов по вашему выбору.

  1. Создайте разреженный файл (предварительно изменив / tmp, чтобы избежать проблем - см. Заключительное примечание):

    15> cd /tmp
    16> dd if=/dev/null of=sparsetest bs=512b seek=5 
    0+0 records in 
    0+0 records out 
    0 bytes (0 B) copied, 5.9256e-05 s, 0.0 kB/s
  2. размер его - он не должен занимать места.

    17> du -sh sparsetest
    0       sparsetest
  3. скопируйте его с помощью cp и проверьте размер

    18> cp sparsetest sparsecp
    19> du -sh sparsecp
    0       sparsecp
  4. теперь скопируйте его с помощью cat и проверьте размер

    20> cat sparsetest > sparsecat
    21> du -sh sparsecat
    1.3M    sparsecat
  5. попробуйте предпочитаемые инструменты, чтобы проверить их поведение

  6. не забывай убирать

Последнее предостережение: подобные эксперименты имеют врожденный шанс поднять вашу известность с вашим локальным сисадмином, если вы делаете это в файловой системе, которая является частью его плана резервного копирования, или имеет решающее значение для благополучия системы. В зависимости от выбора инструмента для резервного копирования ему может потребоваться больше ленточных носителей, чем он когда-либо считал возможным для резервного копирования одного 0-байтового файла, который расширяется до нуля терабайт.

Другие файлы, которые не могут быть скопированы ни с помощью cat, ни cp, будут включать специальные файлы устройства и т. Д. Это зависит от вашей реализации инструмента копирования, если он может дублировать узел устройства или вместо этого он будет весело копировать его содержимое.

Татьяна Хойзер
источник
1
Таким образом, cpсоздает файл так же, как оригинал, в то время как catсоздает новый файл с тем же содержанием.
Цянь
Оба инструмента работают с контентом, но cp (по крайней мере, «современные» реализации) в настоящее время знает о некоторых особенностях, таких как дыры (старые реализации cat будут попадать в эту ловушку). Существуют также файловые системы, которые не знают о концепции разреженных файлов, например, HFS + (MacOS) или FAT (MSDOS, USB-флешки и т. Д.), Что приводит к их увеличению в полном размере. Так что есть созвездия, в которых cp или cat не будут иметь никакого значения на практике.
Татьяна Хойзер
Кстати, в GNU cpесть опция для управления своим поведением в разреженных файлах; как, с --sparse=neverуказанным в командной строке, cpтак же медленно, как cat.
огузов исмаил
6

Согласно комментарию Кейта , cpсохраняет некоторые разрешения и catсоздает новый файл, как umaskуказано. Так $2что разрешение не сохраняется, что $4/vmlinuzдовольно чисто, в то время как если какое-то странное разрешение установлено $3, оно $4/System.mapбудет сохранено.

оборота TheoYou
источник
в этом ли причина атрибута catскованности?
Нихил Мулли
2
Является ли catбыстрее?
Цянь
4

Оба имеют эквивалентную функциональность в этих двух случаях, но cp - это чисто файловая операция. Msgstr "Возьми этот файл и сделай копию там".

С другой стороны, cat предназначена для выгрузки содержимого файла на консоль. «Возьмите этот файл и отобразите его на экране», а затем заставьте ниндзя атаковать экран и перенаправить вывод в другое место.

cp, как правило, будет более эффективным, поскольку не происходит только перенаправление, просто прямое копирование байтов из местоположения A в местоположение B.

кот будет read bytes -> output to console -> intercept output -> redirect to new file .


источник
3
catна самом деле это не так output to console -> intercept output -> redirect to new file, выходной файл для cat может быть stdout или обычным файлом, он будет просто выводиться в файл, если входные данные не совпадают с выходными.
4
catне имеет ничего общего с консолью. Оба catи cpчитаем из входного файла и записываем в выходной файл. С cat, выходной файл открывается с помощью оболочки, тогда как с cp, выходной файл открывается с помощью cp; это не имеет значения в производительности. cpможет быть быстрее, но по совершенно другой причине: некоторые реализации cpпытаются угадать правильный размер блока для производительности в зависимости от исходного и целевого устройств; реализация catне будет беспокоить.
Жиль "ТАК ... перестать быть злым"
2

Это действительно вопрос предпочтений, ИМХО.

Технически нет реальной разницы, если вы не используете команду cp с ключом -p для сохранения владельца файла / группы. Иначе, это то же самое функционально. Ответ Марка гораздо более четкий, хотя и точный.

Кегли
источник
3
cpбез -pсохранения некоторых разрешений. Например, если исходный файл является исполняемым, cpцелевой файл будет исполняемым, но catне будет.
Кит Томпсон
Хорошая точка зрения! Так vmlinuzчто не будет исполняемым, $2есть ли .