Ctrl + D para finalizar a entrada da linha de terminal

21

Se eu fizer

$ cat > file.txt

texto Ctrl- DCtrl-D

Pergunta 1: Se eu não pressione enter, por que eu tenho que 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 é a segunda vez que o arquivo tem 1 linha?

névoa
fonte
2
Esse segmento no guarda-chuva de sites stackexchange tem a resposta que você está procurando: stackoverflow.com/questions/7369170/… . Espero que ajude.
Sim, apesar de não estar relacionado ao python, minha pergunta é uma duplicata.
Nevoeiro
Ao digitar ctrl-z, você realmente está recebendo apenas um novo prompt de shell ou também está recebendo uma mensagem sobre cata interrupção?
precisa saber é o seguinte
Vou atualizar a pergunta
névoa

Respostas:

30

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.

Mark Plotnick
fonte
1
essas coisas são verdadeiras apenas para os terminais de modo canônico . E mesmo nesse caso, eles podem ser alterados.
mikeserv
@mikeserv Isso é verdade. Aqui, eu queria explicar exatamente o que o OP estava vendo. Também considerei descrever o modo terminal bruto / -icanon, outros caracteres especiais, como eles podem ser personalizados, como eles diferem no sistema operacional etc. etc., mas não queria que a resposta fosse muito longa.
Mark Plotnick
O que foi dito acima implica que, se a entrada não estivesse ocorrendo cat, um programa que lesse dados do teclado e não parasse na primeira vez readproduzisse um zero poderia continuar, e o número de D's de controle necessários seria determinado por o número de zeros consecutivos que o programa exigiu para decidir que foi feito?
Supercat
@supercat Um programa pode continuar lendo, se quiser. No exeditor, se você digitar um controle-D como o primeiro caractere de uma linha, o editor mostrará algumas linhas do programa em vez de sair. (Em exe vi, Control-D é um mnemônico para "inativo"). E com muitos shells, se você digitar Control-D, mas tiver trabalhos em execução em segundo plano, o shell o informará disso em vez de sair, mas se você digitar Control-D novamente, o shell decidirá que você realmente deseja sair de qualquer maneira e fará isso.
Mark Plotnick
@ MarkPlotnick: Existe alguma maneira pela qual esses soluços de zero byte podem ser enviados via pipe?
Supercat
19

Isso porque Ctrl+ Dé um hack.

No fundo, Ctrl+ D(apesar de ser chamado de eofcaractere ) não significa realmente final de arquivo: significa "enviar a entrada pendente para o aplicativo agora". Na verdade, é quase o 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 uma readchamada, a leitura de 0 bytes sinaliza o final do arquivo.


Quando você pressiona Ctrl+ Z, a entrada pendente é descartada. Portanto, apenas o que já havia sido enviado ao aplicativo (que é cat) inserindo uma nova linha ou Ctrl+ Dantes de pressionar Ctrl+ Zé processado.

Gilles 'SO- parar de ser mau'
fonte
1
Mais informações sobre ctrl + D de uma das respostas de Gille podem ser encontradas aqui .
Ramesh
Como você disse, Ctrl-D não significa final de arquivo. Na verdade, isso não significa que Ctrl-D seja EOT (fim de texto).
H2ONaCl