
Se eu fizer
$ cat > file.txt
texto Ctrl- DCtrl-D
Pergunta 1: Se eu não pressionar Enter, por que preciso pressionar Ctrl- Dduas vezes?
Se eu fizer
$ cat > file.txt
pa bam pshhh Ctrl-Z
[2]+ Stopped cat > file.txt
$ cat file.txt
$ cat > file.txt
pa bam pshhh
Ctrl-Z
[2]+ Stopped cat > file.txt
$ cat file.txt
pa bam pshhh
Por que na segunda vez o arquivo tem 1 linha?
Responder1
No Unix, a maioria dos objetos que você pode ler e escrever – arquivos comuns, pipes, terminais, unidades de disco brutas – são todos feitos para se parecerem com arquivos.
Um programa como cat
este lê sua entrada padrão assim:
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 várias leituras de 512 bytes, depois uma leitura um pouco mais curta no final do arquivo e 0 se tentasse ler além do final do arquivo. Então, cat
será executado até n
<= 0.
A leitura de um terminal é um pouco diferente. Depois de digitar uma linha, terminada pela Entertecla, 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-Dfor 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 de um arquivo comum ou de um terminal.
Outro caractere especial é Ctrl-Z. Quando você digita, em qualquer lugar de uma linha, o sistema operacional descarta tudo o que você digitou até aquele 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 depois cat
foi interrompido sem ter gravado nada em seu 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, em seguida, Ctrl-Zparou cat
.
Responder2
Isso porque Ctrl+ Dé um hack.
No fundo, Ctrl+ D(apesar de ser chamado deeof
personagem) na verdade não significa fim do arquivo: significa “enviar a entrada pendente para o aplicativo agora”. Na verdade, isso está próximo do significado de Ctrl+ M( eol
), que envia a entrada pendente mais uma nova linha.
Quando você pressiona Ctrl+ Dimediatamente após um Ctrl+ M(ou seja, no início de uma linha) ou após outro Ctrl+ D, a entrada pendente fica vazia. Assim, o aplicativo recebe 0 bytes de entrada. Em umread
chamada, a leitura de 0 bytes sinaliza o fim do arquivo.
Ao pressionar Ctrl+ Z, a entrada pendente é descartada. Assim, apenas o que já foi enviado para a aplicação (que é cat
) inserindo uma nova linha ou Ctrl+ Dantes de pressionar Ctrl+ Zé processado.