Во всех случаях файл усекается.Это потому, что перенаправление обрабатывается оболочкой, которая открывает файл для записи перед вызовом команды.
cat foo > foo
Оболочка обрезает и открывает foo для записи, устанавливает stdout в файл, а затем exec ["cat", "foo"]
.
GNU cat умен и отказывается перенаправлять файл на себя.Это делается путем проверки пары устройство / индекс на дескрипторах входного и выходного файлов;Вы можете прочитать замечательные подробности низкого уровня в src / cat.c .Он печатает сообщение и завершает работу.
У BSD cat такой безопасности нет, но, поскольку файл уже обрезан, читать нечего, ничего не писать, и он останавливается.
Вы можете немного оживить, добавив вместо усечения.
echo hello > foo
cat foo >> foo
Теперь все то же самое, за исключением того, что оболочка открывает файл для добавления вместо усечения.
GNU cat видит, что вы делаете, и останавливается;файл не тронут.
BSD cat зацикливается и добавляет файл к себе, пока ваш диск не заполнится.