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 cat
lê 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, cat
será executado até que n
seja <= 0.
Ler de um terminal é um pouco diferente. Depois que você digita uma linha, finalizada pela Enterchave, read
retorna 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 cat
foi 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 cat
leu e gravou em seu arquivo de saída e depois Ctrl-Zparou cat
.