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.
cp
permite 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, cp
usa 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 … >target
a noclobber
opção no shell comset -C
. Você pode se proteger contra a substituição do arquivo de destino cp
passando a -i
opção ( alias cp='cp -i'
); cp
pedirá confirmação.
Muitas vezes é útil preservar a data do arquivo original. Você pode usar cp -p
para 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 é faster
mais 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