cat a > b
和
cp a b
如果它们在所有意图和目的上功能相同,那么哪一个更快?
答案1
就功能而言,我认为它们是相同的。
如果我必须冒险猜测哪个更快,我会说CP命令,因为它的目的是仅出于复制目的进行文件操作,因此它将为此进行优化。
猫相比之下,意味着连接文件,意味着将多个文件合并成一个系列。如果没有指定文件,它将向控制台显示一个文件(感谢@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
则使用源文件的权限位,并由当前文件修改掩码。
您可以通过在 shell 中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