Perché Ctrl-D (EOF) esce dalla shell?


69

Stai letteralmente "terminando un file" inserendo questa sequenza di escape, ovvero la sessione interattiva della shell è vista come un vero flusso di file dalla shell, come qualsiasi altro flusso di file? In tal caso, quale file?

Oppure, il segnale Ctrl+ Dè solo un segnaposto che significa "l'utente ha finito di fornire input e potresti terminare"?



6
Cordiali saluti, in bash puoi fare set -o ignoreeofper cambiare quel comportamento.
Keith,

Ho avuto lo stesso problema. Il mio errore è stato che ho assegnato accidentalmente il collegamento al profilo konsole su "Ctrl + d". Non è il mio momento più orgoglioso.
Brian Simonsen

Risposte:


79

Il ^Dcarattere (noto anche come \04o 0x4, END OF TRANSMISSION in Unicode) è il valore predefinito per il eofparametro del carattere di controllo speciale del driver terminale o pseudo-terminale nel kernel (più precisamente della ttydisciplina di linea collegata al seriale o pseudo- dispositivo tty ). Questo è il c_cc[VEOF]della termiosstruttura passata alle TCSETS / TCGETS ioctluno problemi al dispositivo terminale di influenzare il comportamento del conducente.

Il comando tipico che invia quelli ioctlsè il sttycomando.

Per recuperare tutti i parametri:

$ stty -a
velocità 38400 baud; file 58; colonne 191; linea = 0;
intr = ^ C; quit = ^ \; cancella = ^ ?; kill = ^ U; eof = ^ D ; eol = <undef>; eol2 = <undef>; swtch = <undef>; inizio = ^ Q; stop = ^ S; susp = ^ Z; rprnt = ^ R; werase = ^ W; lnext = ^ V; flush = ^ O;
min = 1; tempo = 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

Tale eofparametro è rilevante solo quando il dispositivo terminale è in icanonmodalità.

In quella modalità, il driver terminale (non l'emulatore di terminale) implementa un editor di linee molto semplice , in cui è possibile digitare Backspaceper cancellare un carattere, Ctrl-Uper cancellare l'intera riga ... Quando un'applicazione legge dal dispositivo terminale, non vede nulla fino a quando si preme Returna questo punto la read()linea completo, compreso l'ultimo rendimenti LFcarattere (per impostazione predefinita, il driver di terminale si traduce anche l' CRinviato dal terminale al momento Returna LF).

Ora, se vuoi inviare ciò che hai digitato finora senza premere Enter, è qui che puoi inserire il eofpersonaggio. Dopo aver ricevuto quel carattere dall'emulatore di terminale, il driver del terminale invia il contenuto corrente della linea, in modo che l'applicazione che lo esegue readsu di esso lo riceverà così com'è (e non includerà un LFcarattere finale ).

Ora, se la riga corrente era vuota e se l'applicazione avrà letto completamente le righe immesse in precedenza, readrestituirà 0 caratteri.

Ciò significa la fine del file per l'applicazione (quando leggi da un file, leggi fino a quando non c'è più nulla da leggere). Ecco perché si chiama il eofpersonaggio, perché l'invio causa l'applicazione per vedere che non è più disponibile alcun input.

Ora, le shell moderne, al loro prompt non impostano il terminale in icanonmodalità perché implementano il proprio editor di linee che è molto più avanzato di quello integrato nel driver del terminale. Tuttavia, nel loro editor di linee , per evitare di confondere gli utenti, danno al ^Dpersonaggio (o qualunque sia l' eofimpostazione del terminale con alcuni) lo stesso significato (per significare eof).


Una volta ho iniziato a leggere questo commento, sapevo che era stato scritto da Stephane :) Tu, Stephane, sei il mio eroe di Bash e non sono sarcastico. Mi piacerebbe pranzare con te e scegliere il tuo cervello se mai a New York, sto comprando.
Gregg Leventhal,

@GreggLeventhal. Grazie. Le probabilità che io vada a New York in qualsiasi momento presto sono piuttosto scarse.
Stéphane Chazelas,

È EOT anche in ASCII a 7 bit
Bananguin

9

CTRL_D è solo un segnale che dice che questa è la fine di un flusso di testo. Non si termina un file con esso, si termina il flusso di input digitandolo. Inoltre CTRL_D non rappresenta alcun carattere o byte come puoi scoprire con lo strumento 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

5
E la ragione per cui finisce la shell è che la shell è fondamentalmente un processo che accetta input e fa cose con esso. Quando dici che non arriveranno più input, non c'è altro da fare per la shell.
Jenny D,

Mi rendo conto che la sequenza EOF non è contenuta, per esempio, da un file di testo e viene generata dal sistema operativo per segnalare che non ci sono più dati da leggere. Penso che quello che sto veramente chiedendo sia se la sessione del terminale interattivo è vista come un vero flusso di file dalla shell, come qualsiasi altro flusso di file.
Accidenti,

Ho appena modificato la domanda originale per chiarire.
Accidenti

2
sì, il flusso che va a bash è un flusso di input come un altro. CTRL_D segnala che il flusso di input è alla fine e che bash può uscire.
Thorsten Staerk,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.