Warum verlässt Ctrl-D (EOF) die Shell?

68

Beenden Sie eine Datei buchstäblich durch Eingabe dieser Escape-Sequenz, dh wird die interaktive Shell-Sitzung von der Shell wie jeder andere Dateistream als echter Dateistream angesehen? Wenn ja, welche Datei?

Oder ist das Ctrl+ DSignal nur ein Platzhalter, der bedeutet, "der Benutzer hat die Eingabe beendet und Sie können die Eingabe beenden"?

Geeb
quelle
6
Zu Ihrer Information, in bash können Sie set -o ignoreeofdieses Verhalten ändern.
Keith
Ich hatte das gleiche problem Mein Fehler war, dass ich versehentlich die Verknüpfung für das Konsolenprofil "Strg + D" zugewiesen habe. Nicht mein stolzester Moment.
Brian Simonsen

Antworten:

78

Das ^DZeichen (auch bekannt als \04oder 0x4, END OF TRANSMISSION in Unicode) ist der Standardwert für den eofspeziellen Steuerzeichenparameter des Terminal- oder Pseudoterminaltreibers im Kernel (genauer gesagt der Zeilendisziplin, ttydie mit dem seriellen oder Pseudoterminal verbunden ist). tty Gerät ). Das ist die c_cc[VEOF]von der termiosStruktur an die TCSETS bestanden / TCGETS ioctlein Fragen im Zusammenhang mit dem Endgerät des Fahrerverhalten zu beeinflussen.

Der typische Befehl, der diese sendet, ioctlsist der sttyBefehl.

So rufen Sie alle Parameter ab:

$ stty -a
Geschwindigkeit 38400 Baud; Reihen 58; Spalten 191; line = 0;
intr = ^ C; quit = ^ \; Löschen = ^ ?; 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; Zeit = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnlixon -ixoff -iuclc -ixany -imaxbel iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke

Dieser eofParameter ist nur relevant, wenn sich das Endgerät im icanonModus befindet.

In diesem Modus implementiert der Terminal-Treiber (nicht der Terminal-Emulator) einen sehr einfachen Zeileneditor , in den Sie Backspaceeingeben können , um ein Zeichen Ctrl-Uzu löschen, um die gesamte Zeile zu löschen ... Wenn eine Anwendung vom Terminal-Gerät liest, sieht sie nichts bis Sie drücken, Returnan welcher Stelle die read()vollständige Zeile einschließlich des letzten LFZeichens zurückgegeben wird (standardmäßig übersetzt der Terminal-Treiber auch die CRvon Ihrem Terminal Returnan gesendeten Zeichen LF).

Wenn Sie nun das, was Sie bisher eingegeben haben, senden möchten, ohne die Taste zu drücken Enter, können Sie hier das eofZeichen eingeben . Auf dieses Zeichen aus dem Terminal - Emulator empfängt, die Terminal - Treiber tragen den aktuellen Inhalt der Linie, so dass die Anwendung tut das readauf sie wird es erhalten, ist (und es wird keine abschließenden enthält LFZeichen).

Wenn nun die aktuelle Zeile leer war und die Anwendung die zuvor eingegebenen Zeilen vollständig gelesen hat, readwird das Zeichen 0 zurückgegeben.

Dies bedeutet das Ende der Datei für die Anwendung (wenn Sie aus einer Datei lesen, lesen Sie, bis nichts mehr zu lesen ist). Aus diesem Grund wird es als eofZeichen bezeichnet, da die Anwendung beim Senden feststellt, dass keine weiteren Eingaben verfügbar sind.

Moderne Shells versetzen das Terminal nun nicht mehr in den icanonModus, da sie einen eigenen Zeileneditor implementieren, der weitaus fortschrittlicher ist als der in den Terminaltreiber integrierte. In ihrem eigenen jedoch Zeileneditor , die Benutzer nicht zu verwirren, geben sie die ^DZeichen (oder was auch immer die Terminal - eofEinstellung mit einigen ist) die gleiche Bedeutung (bedeuten eof).

Stéphane Chazelas
quelle
Als ich diesen Kommentar las, wusste ich, dass er von Stephane geschrieben wurde :) Du, Stephane, bist mein Held, und ich bin nicht sarkastisch. Ich würde gerne mit Ihnen zu Mittag essen und Ihr Gehirn heraussuchen, wenn Sie jemals in NYC sind.
Gregg Leventhal
@ Gregg Leventhal. Vielen Dank. Die Chancen, dass ich bald nach NYC komme, sind allerdings sehr gering.
Stéphane Chazelas
Es ist EOT sogar in 7-Bit-ASCII
Bananguin
9

STRG_D ist nur ein Signal, das besagt, dass dies das Ende eines Textstroms ist. Sie beenden eine Datei damit nicht, Sie beenden Ihren Eingabestream, indem Sie ihn eingeben. Auch CTRL_D steht nicht für ein Zeichen oder Byte, wie Sie mit dem Tool hexdump herausfinden können:

# 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
Thorsten Staerk
quelle
5
Und der Grund, warum die Shell beendet wird, ist, dass die Shell im Grunde genommen ein Prozess ist, der Eingaben akzeptiert und Sachen damit macht. Wenn Sie sagen, dass keine weiteren Eingaben mehr kommen werden, hat die Shell nichts mehr zu tun.
Jenny D
Mir ist klar, dass die EOF-Sequenz beispielsweise nicht in einer Textdatei enthalten ist und vom Betriebssystem generiert wird, um zu melden, dass keine weiteren Daten zu lesen sind. Ich denke, ich frage wirklich, ob die interaktive Terminalsitzung von der Shell wie jeder andere Dateistream als echter Dateistream angesehen wird.
Geeb
Gerade bearbeitet die ursprüngliche Frage zu klären.
Geeb
2
Ja, der Stream, der zur Bash geht, ist ein Eingabestream wie jeder andere. CTRL_D signalisiert, dass der Eingabestream beendet ist und die Bash beendet werden kann.
Thorsten Staerk