
Unter Linux ist ein Terminal mit einer Shell verknüpft. Das Terminal sendet Eingaben an die Shell (zum Beispiel: pwd
), und die Shell sendet die Ausgabe zurück an das Terminal (zum Beispiel: /home/paul
).
Dieses Diagramm zeigt die Beziehung zwischen einem Terminal und einer Shell (nehmen Sie an, dass das von mir verwendete Terminal ist gnome-terminal
und die Shell ist bash
):
Jetzt möchte ich wissen, welchen Mechanismus das Terminal und die Shell zum Datenaustausch verwenden. Ich denke, das passiert:
- Bei
gnome-terminal
der Ausführung wird eine Datei erstellt, die einen seriellen Port im/dev/pts
Verzeichnis darstellt (nehmen wir an, der Dateiname ist/dev/pts/0
). gnome-terminal
führt dann die damit verbundene Shell aus (zum Beispiel:bash
) und übergibt ihr den PTS-Dateinamen (der PTS-Dateiname kann beispielsweise über die Befehlszeilenargumente übergeben werden).- Jetzt würden sowohl
gnome-terminal
als auchbash
von mit dem Lesen beginnen/dev/pts/0
. - Wenn
gnome-terminal
Daten an gesendet werden sollenbash
, schreibt es diese Daten in/dev/pts/0
undbash
liest sie von/dev/pts/0
. - Wenn
bash
Daten an gesendet werden sollengnome-terminal
, schreibt es diese Daten in/dev/pts/0
undand
gnome-terminal
liest diese Daten von/dev/pts/0
.
Dieses Diagramm zeigt, was ich gerade erklärt habe:
Habe ich das richtig verstanden?
Notiz: Natürlich könnte die pts-Datei eine tty-Datei sein, wenn wir virtuelle Terminals verwenden (d. h. wenn wir keine GUI verwenden), aber die Logik wäre immer noch dieselbe.
Antwort1
Ihnen fehlt ein notwendiges Teil. Pseudo-TTY-Geräte sind nicht symmetrisch wie Sockets. Es gibt ein Master-Ende und ein Slave-Ende. Die Dateien darin /dev/pts
stellen die Slave-Geräte dar.
Der Terminalemulator erstellt ein Pseudo-TTY durch Aufruf von openpty
(oder forkpty
plus openpty
einige Bonus-Setups für den üblichen Fall, dass Sie einen neuen Prozess auf Ihrem neuen TTY ausführen möchten). Auf einer niedrigeren Ebene beinhaltet dies das Öffnen /dev/ptmx
und Ausführen einiger magischer Ioctls.
Als Ergebnis des Aufrufs openpty
erhält der Terminalemulator ein Paar Dateideskriptoren und kann auch den Namen der Datei abrufen, die /dev/pts
dem Slave entspricht. Der Master erhält keinen individuellen Namen, da es nie notwendig ist, dass ein untergeordneter Prozess die Datei anhand des Namens öffnet.
Master- und Slave-Geräte verhalten sich wie die gegenüberliegenden Enden eines Sockets: Was Sie an einem Ende schreiben, wird am anderen Ende gelesen. Da es sich jedoch um ein TTY handelt, werden alle TTY-Modi auf dem Weg dorthin auf die Daten angewendet.
Wenn Sie beispielsweise ein Terminalemulator sind und einen Tastendruck empfangen , sollten Sie in den Master-Dateideskriptor Aschreiben . Dies entspricht direkt dem Senden dieses Bytes über die serielle Leitung vom Terminal zum Computer. Es wird vom Slave gelesen (von dem Programm, das es liest – z. B. der Shell).'a'
'a'
Wenn Sie einen Tastendruck empfangen, Dwährend die CtrlTaste gedrückt ist, sollten Sie ein 4
Byte ( 'D' ^ 0x40
) in den Master-Dateideskriptor schreiben. (Denn das ist, was ein echtes Terminal über die Leitung sendet.) Was als nächstes passiert, hängt vom TTY-Modus ab. Im Raw-Modus sieht das Programm, das das Slave-TTY liest, ein 4
Byte. Im Cooked-Modus aktiviert das TTY das Verhalten „EOF-Sondertaste gedrückt“.
In umgekehrter Richtung findet ebenfalls eine gewisse Verarbeitung statt. Wenn ein Programm '\n'
auf das Slave-TTY schreibt, erhalten Sie aufgrund der Nachbearbeitung wahrscheinlich "\r\n"
Daten auf dem Master-Dateideskriptor .onlcr
Abschnitt „Geschichte“, überspringen Sie ihn, wenn Sie gelangweilt sind
Vor langer Zeit hatten die Slave-Geräte Namen wie /dev/ttyp0
und jedes hatte einen entsprechenden Master wie /dev/ptyp0
. Sie wurden nicht dynamisch erstellt. Ein Terminalemulator konnte sie einfach alle durchsuchen, um eins zu finden, das gerade nicht verwendet wird, und es verwenden. Die Verwaltung von Besitz und Berechtigungen war ein Problem. xterm
war setuid-root, nur damit es den Slave chownen konnte.
Das neue Schema mit der Bezeichnung „UNIX98 ptys“ handhabt die Geräteerstellung und den Gerätebesitz über die magischen ioctls, so dass Dateien nur dann angezeigt werden, /dev/pts
wenn sie verwendet werden, und sie dem Benutzer gehören, der das Programm ausgeführt hat, mit dem sie erstellt wurden.