Strg + D zum Beenden der Terminalleitungseingabe

21

Wenn ich mache

$ cat > file.txt

Text Ctrl- DCtrl-D

Frage 1: Wenn ich nicht drücken gebe, warum habe ich zu drücken Ctrl- Dzweimal?

Wenn ich mache

$ 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

Warum ist das zweite mal die datei mit 1 zeile?

Nebel
quelle
2
Dieser Thread unter dem Dach von stackexchange sites hat die Antwort, die Sie suchen: stackoverflow.com/questions/7369170/… . Ich hoffe es hilft.
Ja, obwohl nicht mit Python verwandt, ist meine Frage ein Duplikat.
Mist
Wenn Sie ctrl-z eingeben, erhalten Sie wirklich nur eine neue Shell-Eingabeaufforderung, oder erhalten Sie auch eine Meldung darüber, catdass Sie gestoppt werden?
Mark Plotnick
Ich werde die Frage aktualisieren
Nebel

Antworten:

30

In Unix sind die meisten Objekte, die Sie lesen und schreiben können - normale Dateien, Pipes, Terminals, Raw-Laufwerke - alle so angelegt, dass sie Dateien ähneln.

Ein Programm wie catliest von seiner Standardeingabe wie folgt:

n = read(0, buffer, 512);

das fragt nach 512 Bytes. nist die Anzahl der tatsächlich gelesenen Bytes oder -1, wenn ein Fehler vorliegt.

Wenn Sie dies wiederholt mit einer normalen Datei durchgeführt haben, erhalten Sie eine Reihe von Lesevorgängen von 512 Byte, dann einen etwas kürzeren Lesevorgang am hinteren Ende der Datei und dann den Wert 0, wenn Sie versucht haben, nach dem Ende der Datei zu lesen. Läuft so lange, catbis n<= 0 ist.

Das Lesen von einem Terminal ist etwas anders. Nachdem Sie eine mit der EnterTaste abgeschlossene readZeile eingegeben haben, wird nur diese Zeile zurückgegeben.

Es gibt einige Sonderzeichen, die Sie eingeben können. Eins ist Ctrl-D. Wenn Sie dies eingeben, sendet das Betriebssystem die gesamte aktuelle Zeile, die Sie eingegeben haben (jedoch nicht die Zeile Ctrl-Dselbst), an das Programm, das den Lesevorgang ausführt. Und hier ist der Zufall: Wenn Ctrl-Des sich um das erste Zeichen in der Zeile handelt, wird dem Programm eine Zeile mit der Länge 0 gesendet - genau wie das Programm sehen würde, wenn es gerade am Ende einer normalen Datei angelangt wäre. cat Es muss nichts anders gemacht werden , egal ob es sich um das Lesen aus einer normalen Datei oder einem Terminal handelt.

Eine weitere Besonderheit ist Ctrl-Z. Wenn Sie es an einer beliebigen Stelle in einer Zeile eingeben, verwirft das Betriebssystem alles, was Sie bis dahin eingegeben haben, und sendet ein SIGTSTP-Signal an das Programm, das es normalerweise anhält (anhält) und die Kontrolle an die Shell zurückgibt.

Also in deinem Beispiel

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

Sie haben einige Zeichen eingegeben, die verworfen wurden, und wurden dann catgestoppt, ohne etwas in die Ausgabedatei geschrieben zu haben.

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

Sie haben eine Zeile eingegeben, die catdie Ausgabedatei gelesen und in diese geschrieben hat, und dann die Ctrl-Zangehaltene cat.

Mark Plotnick
quelle
1
Diese Dinge gelten nur für Terminals im kanonischen Modus . Und auch in diesem Fall können sie geändert werden.
mikeserv
@mikeserv Das stimmt. Hier wollte ich nur erklären, was das OP sah. Ich habe darüber nachgedacht, auch den Raw / -icanon-Terminalmodus, andere Sonderzeichen, die Anpassbarkeit, die Unterschiede nach Betriebssystem usw. zu beschreiben, wollte aber die Antwort nicht zu lang machen.
Mark Plotnick
Bedeutet das oben Gesagte cat, dass ein Programm, das Daten von der Tastatur liest und beim ersten Mal nicht stoppt, readeine Null liefert, ohne Unterbrechung weiterarbeiten kann und die Anzahl der erforderlichen Control-Ds durch bestimmt wird Wie viele aufeinanderfolgende Nullen benötigt das Programm, um zu entscheiden, ob es ausgeführt wurde?
Supercat
@supercat Ein Programm kann weiterlesen, wenn es möchte. exWenn Sie im Editor ein Steuerelement-D als erstes Zeichen einer Zeile eingeben, zeigt der Editor einige Zeilen des Programms an, anstatt es zu beenden. (In exund viist Control-D ein Mnemon für "down"). Wenn Sie bei vielen Shells Control-D eingeben, aber Jobs im Hintergrund ausgeführt werden, werden Sie von der Shell darüber informiert, anstatt sie zu beenden. Wenn Sie Control-D jedoch erneut eingeben, entscheidet die Shell, dass Sie sie trotzdem beenden möchten, und wird so gemacht.
Mark Plotnick
@ MarkPlotnick: Gibt es eine Möglichkeit, wie diese Null-Byte-Schluckauf über Pipe gesendet werden können?
Supercat
19

Das liegt daran, dass Ctrl+ Dein Hack ist.

Tief im Inneren bedeutet Ctrl+ D(obwohl es als eofCharakter bezeichnet wird ) nicht das Ende der Datei: Es bedeutet "Senden der ausstehenden Eingabe an die Anwendung jetzt". Dies entspricht in etwa der Bedeutung von Ctrl+ M( eol), das die anstehende Eingabe plus eine neue Zeile sendet.

Wenn Sie unmittelbar nach einem + (dh am Anfang einer Zeile) oder nach einem anderen + + Ctrl+ drücken , ist die anstehende Eingabe leer. Somit erhält die Anwendung 0 Bytes an Eingaben. Bei einem Aufruf signalisiert das Lesen von 0 Bytes das Ende der Datei.DCtrlMCtrlDread


Wenn Sie Ctrl+ drücken Z, wird die anstehende Eingabe verworfen. Somit wird nur das verarbeitet, was bereits catdurch Eingabe einer neuen Zeile oder eines Ctrl+ Dvor dem Drücken von Ctrl+ an die Anwendung gesendet wurde Z.

Gilles 'SO - hör auf böse zu sein'
quelle
1
Weitere Informationen zu Strg + D aus einer von Gilles Antworten finden Sie hier .
Ramesh
Wie Sie sagten, bedeutet Strg-D nicht das Ende der Datei. Tatsächlich heißt das nicht, dass Strg-D EOT (Ende des Textes) ist.
H2ONaCl