В Unix большинство объектов, которые вы можете читать и записывать - обычные файлы, каналы, терминалы, жесткие диски - все они напоминают файлы.
Программа вроде catчитает из своего стандартного ввода вот так:
n = read(0, buffer, 512);
который просит 512 байт. nколичество фактически прочитанных байтов, или -1, если есть ошибка.
Если вы делали это неоднократно с обычным файлом, вы получите кучу 512-байтовых чтений, затем несколько более короткое чтение в конце файла, затем 0, если вы попытались прочитать после конца файла. Итак, catбудет работать до тех пор, пока не nстанет <= 0.
Чтение из терминала немного отличается. После ввода строки, оканчивающейся Enterклавишей, readвозвращается только эта строка.
Есть несколько специальных символов, которые вы можете напечатать. Один есть Ctrl-D. Когда вы набираете это, операционная система отправляет всю введенную вами текущую строку (но не Ctrl-Dсаму) в программу, выполняющую чтение. И вот случайная вещь: если Ctrl-Dэто первый символ в строке, программе отправляется строка длиной 0 - точно так же, как программа увидит, добралась ли она до конца обычного файла. cat не нужно ничего делать иначе , будь то чтение из обычного файла или из терминала.
Еще один особый персонаж Ctrl-Z. Когда вы набираете его в любом месте строки, операционная система отбрасывает все, что вы набрали, до этой точки и отправляет сигнал SIGTSTP в программу, которая обычно останавливает (приостанавливает) его и возвращает управление оболочке.
Так в вашем примере
$ cat > file.txt
pa bam pshhh<Ctrl+Z>
[2]+ Stopped cat > file.txt
Вы набрали несколько символов, которые были отброшены, а затем catостановлены, ничего не записав в его выходной файл.
$ cat > file.txt
pa bam pshhh
<Ctrl+Z>
[2]+ Stopped cat > file.txt
Вы набрали одну строку, которая catпрочитала и записала в свой выходной файл, а затем Ctrl-Zостановилась cat.