Existe uma diferença entre esses dois comandos?

Existe uma diferença entre esses dois comandos?
cat a > b

e

cp a b

Se eles são funcionalmente iguais para todos os efeitos, qual deles é mais rápido?

Responder1

Em termos de funcionalidade acho que são iguais.

Se eu tivesse que arriscar um palpite sobre o que é mais rápido, diria que oCPcomando porque seu objetivo é realizar operações de arquivo apenas para fins de cópia, portanto, seria otimizado para isso.

gato, por outro lado, significaconcatenararquivos, ou seja, juntar vários arquivos em uma série. Se nenhum arquivo for especificado, ele exibirá um arquivo no console (obrigado a @bahamat por nos lembrar). Neste exemplo a saída é redirecionada para outro arquivo. Acho que essa indireção seria menos eficiente que uma direta cp.

Não sei se a diferença seria perceptível para arquivos de tamanho normal, embora fosse interessante cronometrar isso em arquivos muito grandes. Eu acho que alguém poderia fazer testes repetidos com /usr/bin/time e ver se um é consistentemente mais rápido/mais lento que o outro.

Você tem algum motivo específico para perguntar sobre isso ou é apenas uma simples curiosidade (nada de errado com isso, é claro)

Responder2

Funcionalmente semelhantes, mas especificamente diferentes. Essencialmente, os dois leem vários dados do primeiro arquivo e gravam-nos em outro arquivo.

Quando eu faço umtraçono 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)                           = ?

Responder3

Não há muita diferença: ambos copiam o conteúdo do arquivo antigo para um novo arquivo com o mesmo conteúdo. Ambos substituem o destino se for um arquivo existente.

Alguns sistemas antigos podem parar de copiar ou truncar linhas se você tentar copiar arquivos binários com cat, porque eles podem engasgar com caracteres nulos. Eu não acho que nenhum sistema unix que você encontre agora tenha um problema aí. cpé garantido que não terá problemas.

cppermite especificar um diretório como destino: o arquivo é copiado para ter o mesmo nome do original, no novo diretório.

Se o destino não existir, cpusa os bits de permissão do arquivo de origem, modificados pelo atualumask.

Você pode se proteger contra a substituição do arquivo de destino definindo cat … >targeta noclobberopção no shell comset -C. Você pode se proteger contra a substituição do arquivo de destino cppassando a -iopção ( alias cp='cp -i'); cppedirá confirmação.

Muitas vezes é útil preservar a data do arquivo original. Você pode usar cp -ppara isso.

O desempenho irá variar dependendo do tamanho do arquivo, do sistema de arquivos, do tipo de disco de origem e de destino, do sistema operacional, etc.Para cópias brutas de disco no Linux, não encontrei quase nenhuma diferença.

Responder4

Parece que gato é fastermais que 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

informação relacionada