Отличие cp и cat

Скопировать файлы из консоли можно двумя способами: cp a b и cat a > b.
Разницу между ними можно отчасти понять из сути самих команд: cp копирует файл, а cat создаёт новый файл с таким же содержимым.
В большинстве случаев эти два метода взаимозаменяемы, но существует пара нюансов.

Права

TL;DR: cp сохраняет оригинальные права на файл, cat — нет.

Создадим тестовый скрипт:

$ touch a.sh

По умолчанию для новых файлов мы получаем права только на чтение и запись:

$ ls -l a.sh
-rw-r--r--  1 tonyganch  foo  0 Oct  7 09:29 a.sh

Добавим право на исполнение:

$ chmod +x a.sh
$ ls -l a.sh
-rwxr-xr-x  1 tonyganch  foo  0 Oct  7 09:29 a.sh

А теперь сделаем две копии этого скрипта и проверим их права:

$ cp a.sh b.sh
$ ls -l b.sh
-rwxr-xr-x  1 tonyganch  foo  0 Oct  7 09:30 b.sh

$ cat a.sh > c.sh
$ ls -l c.sh
-rw-r--r--  1 tonyganch  foo  0 Oct  7 09:30 c.sh

Как видим, cp скопировал скрипт вместе с правами оригинального файла, cat же сохранил только содержимое файла.

Разрежённые файлы

Пользователи Mac OS могут дальше не читать.

В некоторых файловых системах существует понятие разрежённых файлов (sparse files).
Это такие чудесные файлы, в которых последовательность нулевых битов заменяется на информацию об этой последовательности.
Иными словами, пустое пространство файла не занимает физического места на диске.

В терминале это можно сделать так:

$ dd if=/dev/null of=a.sh bs=512b seek=5

Нас интересует размер получившегося файла, поэтому взвешиваем его:

$ du -sh a.sh
0       a.sh

Теперь копируем скрипт и взвешиваем результат:

$ cp a.sh b.sh
$ du -sh b.sh
0       a.sh

$ cat a.sh > c.sh
$ du -sh c.sh
1,3M    c.sh

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