Ctrl + D para terminar a entrada da linha de terminal

19

Se eu fizer

$ cat > file.txt

textCtrl-DCtrl-D

Pergunta 1: Se eu não pressionar enter, por que eu tenho que pressionar Ctrl - D duas vezes?

Se eu fizer

$ cat > file.txt

pa bam pshhhCtrl-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 a segunda vez o arquivo com 1 linha?

    
por mist 06.01.2015 / 00:38

2 respostas

29

No Unix, a maioria dos objetos que você pode ler e gravar - arquivos comuns, canais, terminais, unidades de disco brutas - são todos feitos para se assemelhar a 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, você receberia um monte de leituras de 512 bytes, depois uma leitura um pouco mais curta no final do arquivo, então 0 se você tentasse ler além do final do arquivo. Arquivo. Então, cat será executado até n ser < = 0.

Ler de um terminal é um pouco diferente. Depois que você digitar uma linha, terminada pela tecla Enter , read retornará apenas aquela linha.

Existem alguns caracteres especiais que você pode digitar. Um é Ctrl-D . Quando você digita isto, o sistema operacional envia toda a linha atual que você digitou (mas não o próprio Ctrl-D ) para o programa que está fazendo a leitura. E aqui está a coisa casual: se Ctrl-D é o primeiro caractere na linha, o programa recebe uma linha de comprimento 0 - assim como o programa veria se chegasse ao fim de uma linha. arquivo comum. cat não precisa fazer nada diferente , seja lendo um arquivo comum ou 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 para o programa, que normalmente para (pausa) e retorna o controle para o 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, então cat foi parado sem ter escrito nada em seu arquivo de saída.

$ cat > file.txt
pa bam pshhh
<Ctrl+Z>
[2]+  Stopped         cat > file.txt

você digitou em uma linha, que cat leu e escreveu em seu arquivo de saída, e então o Ctrl-Z parou cat .

    
por 06.01.2015 / 01:43
19

Isso porque Ctrl + D é um hack.

No fundo, Ctrl + D (apesar de ser chamado de eof character ) na verdade não significa end-of-file: significa" enviar a entrada pendente para o aplicativo agora ". Isso é realmente próximo do significado de Ctrl + M ( eol ), que envia a entrada pendente mais uma nova linha.

Quando você pressionar Ctrl + D imediatamente depois de uma Ctrl + M (isto é, no início de um line) ou depois de outra Ctrl + D , a entrada pendente está vazia. Assim, o aplicativo recebe 0 bytes de entrada. Em uma read chamada, a leitura de 0 bytes sinaliza o final do arquivo.

Quando você pressiona 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 + D antes de pressionar Ctrl + Z é processado.

    
por 06.01.2015 / 01:44