No Unix, a maioria dos objetos que você pode ler e escrever - arquivos comuns, tubulações, terminais, unidades de disco bruto - são todos criados para se parecer com arquivos.
Um programa como catlê sua entrada padrão como esta:
n = read(0, buffer, 512);
que pede 512 bytes. né o número de bytes realmente lidos ou -1 se houver um erro.
Se você fizesse isso repetidamente com um arquivo comum, obteria um monte de leituras de 512 bytes, uma leitura um pouco mais curta no final do arquivo e, em seguida, 0 se você tentasse ler além do final do arquivo. Portanto, catserá executado até que nseja <= 0.
Ler de um terminal é um pouco diferente. Depois que você digita uma linha, finalizada pela Enterchave, readretorna apenas essa linha.
Existem alguns caracteres especiais que você pode digitar. Um é Ctrl-D. Quando você digita isso, o sistema operacional envia toda a linha atual que você digitou (mas não a Ctrl-Dprópria) para o programa que está fazendo a leitura. E aqui está o acaso: se Ctrl-Dé o primeiro caractere da linha, o programa recebe uma linha de comprimento 0 - exatamente como o programa veria se chegasse ao final de um arquivo comum. cat não precisa fazer nada diferente , seja lendo um arquivo comum ou um terminal.
Outro personagem especial é Ctrl-Z. Quando você digita, em qualquer lugar da linha, o sistema operacional descarta o que você digitou até esse ponto e envia um sinal SIGTSTP ao programa, que normalmente o interrompe (pausa) e retorna o controle ao shell.
Então no seu exemplo
$ cat > file.txt
pa bam pshhh<Ctrl+Z>
[2]+ Stopped cat > file.txt
você digitou alguns caracteres que foram descartados e catfoi interrompido sem ter gravado nada no arquivo de saída.
$ cat > file.txt
pa bam pshhh
<Ctrl+Z>
[2]+ Stopped cat > file.txt
você digitou uma linha, que catleu e gravou em seu arquivo de saída e depois Ctrl-Zparou cat.