Есть ли разница между этими двумя командами?

Есть ли разница между этими двумя командами?
cat a > b

и

cp a b

Если они функционально одинаковы для всех целей и задач, какой из них быстрее?

решение1

По функциональности я думаю они одинаковы.

Если бы мне пришлось предположить, что быстрее, я бы сказал, чтосркоманда, поскольку ее цель — выполнять файловые операции только для копирования, поэтому она будет оптимизирована для этого.

кот, напротив, подразумеваетсяконкатенироватьfiles, что означает объединение нескольких файлов в серию. Если файл не указан, он выведет файл на консоль (спасибо @bahamat за напоминание). В этом примере вывод перенаправляется в другой файл. Я думаю, что это косвенное обращение будет менее эффективным, чем прямое cp.

Я не знаю, будет ли разница заметна для файлов обычного размера, хотя было бы интересно замерить время для очень больших файлов. Думаю, можно провести повторные испытания с /usr/bin/time и посмотреть, будет ли один из них постоянно быстрее/медленнее другого.

У вас есть какая-то особая причина спрашивать об этом или это просто любопытство (в этом, конечно, нет ничего плохого)?

решение2

Функционально похожи, но конкретно отличаются. По сути, они оба считывают кучу данных из одного файла, записывают их в другой файл.

Когда я делаюследна Linux:

$ strace cat /etc/fstab > test.txt
...
open("/etc/fstab", O_RDONLY|O_LARGEFILE) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=691, ...}) = 0
fadvise64_64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0
read(3, "# /etc/fstab: static file system"..., 32768) = 691
write(1, "# /etc/fstab: static file system"..., 691) = 691
read(3, "", 32768)                      = 0
close(3)                                = 0
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?

$ strace cp /etc/fstab test.log
...
open("/etc/fstab", O_RDONLY|O_LARGEFILE) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=691, ...}) = 0
open("test.log", O_WRONLY|O_CREAT|O_EXCL|O_LARGEFILE, 0644) = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
read(3, "# /etc/fstab: static file system"..., 32768) = 691
write(4, "# /etc/fstab: static file system"..., 691) = 691
read(3, "", 32768)                      = 0
close(4)                                = 0
close(3)                                = 0
_llseek(0, 0, 0xbfaa3fb0, SEEK_CUR)     = -1 ESPIPE (Illegal seek)
close(0)                                = 0
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?

решение3

Большой разницы нет: оба копируют содержимое старого файла в новый файл с тем же содержимым. Оба перезаписывают целевой файл, если это существующий файл.

Некоторые старые системы могут прекратить копирование или обрезать строки, если вы попытаетесь скопировать двоичные файлы с помощью cat, поскольку они могут захлебнуться нулевыми символами. Я не думаю, что какая-либо система unix, с которой вы, вероятно, столкнетесь сейчас, имеет с этим проблему. cpгарантированно не будет иметь проблем.

cpпозволяет указать каталог в качестве места назначения: файл копируется в новый каталог с тем же именем, что и у оригинала.

Если место назначения не существует, cpиспользуются биты разрешений исходного файла, измененные текущимumask.

Вы можете защитить целевой файл от перезаписи, cat … >targetустановив noclobberопцию в оболочке с помощьюset -C. Вы можете защитить целевой файл от перезаписи, cpпередав -iпараметр ( alias cp='cp -i'); cpзапросит подтверждение.

Часто бывает полезно сохранить дату исходного файла. cp -pДля этого можно использовать.

Производительность будет зависеть от размера файла, файловой системы, типа исходного и целевого диска, операционной системы и т. д.Для копий сырых дисков под Linux, я не обнаружил практически никакой разницы.

решение4

Похоже на кошку, fasterчем на cp

root@SHW:/tmp# time cp debug.log test1
real    0m0.021s
user    0m0.000s
sys 0m0.000s
root@SHW:/tmp# time cat debug.log > test2
real    0m0.013s
user    0m0.000s
sys 0m0.000s
root@SHW:/tmp# du -h debug.log 
4.0K    debug.log
root@SHW:/tmp# file debug.log
debug.log: ASCII text

Связанный контент