Por que o Ctrl-D (EOF) sai do shell?

53

Você está literalmente "terminando um arquivo" inserindo essa seqüência de escape, ou seja, a sessão do shell interativo é vista como um fluxo de arquivo real pelo shell, como qualquer outro fluxo de arquivo? Em caso afirmativo, qual arquivo?

Ou o sinal Ctrl + D é apenas um espaço reservado que significa "o usuário terminou de fornecer entrada e você pode terminar"?

    
por Geeb 21.01.2014 / 11:45

2 respostas

62

O caractere ^D (também conhecido como ou 0x4) é o valor padrão para o parâmetro de caractere de controle especial eof do terminal ou driver de pseudo-terminal no kernel (mais precisamente do tty linha disciplina anexada ao dispositivo serial ou pseudo-tty ). Essa é a c_cc[VEOF] da estrutura termios passada para os problemas TCSETS / TCGETS ioctl one no dispositivo terminal para afetar o comportamento do driver.

O comando típico que envia os ioctls é o comando stty .

Para recuperar todos os parâmetros:

$ stty -a
speed 38400 baud; rows 58; columns 191; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O;
min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke

Esse parâmetro eof só é relevante quando o dispositivo terminal está no modo icanon .

Nesse modo, o driver de terminal (não o emulador de terminal) implementa um editor de linhas muito simples, onde você pode digitar Backspace para apagar um caractere, Ctrl-U para apagar toda a linha ... Quando uma aplicação lê o dispositivo terminal, não vê nada até que você pressione Retornar ponto em que read() retorna a linha completa incluindo o último caractere LF (por padrão, o driver do terminal também traduz o CR enviado pelo seu terminal ao Retornar para LF ).

Agora, se você quiser enviar o que você digitou até agora sem pressionar Enter , é aí que você pode inserir o caractere eof . Ao receber esse caractere do emulador de terminal, o driver do terminal submete o conteúdo atual da linha, para que o aplicativo que faz o read receba como está (e não incluirá um caractere LF final).

Agora, se a linha atual estava vazia, e desde que o aplicativo tenha lido completamente as linhas inseridas anteriormente, o read retornará 0 caractere.

Isso significa fim do arquivo para o aplicativo (quando você lê um arquivo, lê até que não haja mais nada para ler). É por isso que ele é chamado de caractere eof , porque o envio faz com que o aplicativo veja que não há mais entrada disponível.

Agora, as shells modernas, em seu prompt, não configuram o terminal no modo icanon porque implementam seu próprio editor de linhas , que é muito mais avançado que o driver de terminal integrado. No entanto, em seu próprio editor de linhas , para confundir os usuários, eles dão o caractere ^D (ou qualquer que seja a configuração eof do terminal com alguns) o mesmo significado (para significar eof ).

    
por 21.01.2014 / 13:47
8

CTRL_D é apenas um sinal dizendo que este é o fim de um fluxo de texto. Você não finaliza um arquivo com ele, termina seu fluxo de entrada digitando-o. Também CTRL_D não representa nenhum caracter ou byte como você pode descobrir com a ferramenta hexdump:

# cat >test.txt
asdf# hexdump -C test.txt 
00000000  61 73 64 66                                       |asdf|
00000004
# ll test.txt 
-rw-r--r-- 1 root root 4 Jan 21 11:55 test.txt
    
por 21.01.2014 / 11:58