Terminal-Emulatoren
Die Masterseite ersetzt die Leitung (das TX / RX-Kabelpaar), die zum Terminal führt.
Das Terminal zeigt die Zeichen an, die es auf einer der Leitungen empfängt (einige davon sind Steuerzeichen und veranlassen es, den Cursor zu bewegen, die Farbe zu ändern ...), und sendet die Zeichen, die den von Ihnen eingegebenen Tasten entsprechen, auf eine andere Leitung.
Terminal-Emulatoren wie xterm unterscheiden sich nicht, außer dass sie Zeichen auf der Masterseite lesen und schreiben, anstatt Zeichen auf Drähten zu senden und zu empfangen. Sobald sie das Slave-Terminal erzeugt haben und Ihre Shell darauf gestartet haben, berühren sie das nicht mehr. Zusätzlich zur Emulation des Adernpaares kann xterm auch einige der Liniendisziplin-Eigenschaften über diesen Dateideskriptor zur Masterseite ändern. Beispielsweise können sie die Größenattribute aktualisieren, sodass ein SIGWINCH an die Anwendungen gesendet wird, die mit dem Slave-Pty interagieren, um sie über eine geänderte Größe zu benachrichtigen.
Ansonsten ist im Terminal / Terminal-Emulator wenig Intelligenz vorhanden .
Was Sie auf ein Endgerät (wie den Pty-Slave) schreiben, ist das, was Sie dort anzeigen, was Sie daraus lesen, ist das, was Sie dort eingegeben haben. Daher ist es für den Terminal-Emulator nicht sinnvoll, darauf zu lesen oder zu schreiben . Sie sind die am anderen Ende.
Die tty line Disziplin
Ein Großteil der Intelligenz liegt in der Disziplin der Tty-Line . Die Leitungsdisziplin ist ein Softwaremodul (im Treiber, im Kernel), das auf ein serielles / pty-Gerät aufgeschoben wird, das sich zwischen diesem Gerät und der Leitung / Leitung befindet (die Masterseite für ein pty).
Eine serielle Leitung kann am anderen Ende ein Terminal haben, aber auch eine Maus oder einen anderen Computer für die Vernetzung. Sie können beispielsweise eine SLIP-Leitungsdisziplin anschließen, um eine Netzwerkschnittstelle über ein serielles Gerät (oder ein Pty-Gerät) zu legen, oder Sie können eine Tty- Leitungsdisziplin einrichten . Die tty-Zeilendisziplin ist die Standard-Zeilendisziplin, zumindest unter Linux für serielle und pty-Geräte. Unter Linux können Sie die Liniendisziplin mit ändern ldattach
.
Sie können den Effekt des Deaktivierens der tty line-Disziplin durch Ausgabe stty raw -echo
feststellen (beachten Sie, dass die Bash-Eingabeaufforderung oder andere interaktive Anwendungen wie vi
das Terminal auf den genauen Modus eingestellt sind, den sie benötigen, sodass Sie eine dumme Anwendung verwenden möchten, die dies gerne cat
erlebt). Dann wird alles, was auf das Slave-Endgerät geschrieben wird, sofort auf die Masterseite gesendet, damit xterm lesen kann, und jedes von xterm auf die Masterseite geschriebene Zeichen kann sofort vom Slave-Gerät gelesen werden.
In der Leitungsdisziplin ist der endgeräteinterne Leitungseditor implementiert. Wenn Sie beispielsweise stty icanon echo
(wie in der Standardeinstellung) a
Folgendes eingeben, schreibt xterm a
an den Master, und die Zeilendisziplin gibt es zurück (stellt ein a
zum Lesen xterm
zur Verfügung, um es anzuzeigen), stellt jedoch nichts zum Lesen auf der Slave-Seite zur Verfügung . Wenn Sie dann Backspace eingeben, sendet xterm ein ^?
oder ^H
-Zeichen, die Zeilendisziplin (als die ^?
oder ^H
entspricht der erase
Zeilendisziplin-Einstellung) sendet zurück auf den Master ein ^H
, space
und ^H
um das xterm
zu löschena
Sie haben gerade auf dem Bildschirm getippt und immer noch nichts von der Slave-Seite an die Anwendung gesendet, sondern nur den internen Zeileneditor-Puffer aktualisiert, um die a
zuvor getippten Einträge zu entfernen .
Wenn Sie dann die Eingabetaste drücken, sendet xterm ^M
(CR), das die Zeilendisziplin bei der Eingabe in ein ^ J (LF) konvertiert, und sendet, was Sie bisher zum Lesen auf der Slave-Seite eingegeben haben (eine Anwendung, die auf liest /dev/pts/x
, erhält was Sie haben die LF eingegeben, aber nicht die, a
seit Sie sie gelöscht haben. Auf der Masterseite werden CR und LF gesendet, um den Cursor in die nächste Zeile und zum Anfang des Bildschirms zu bewegen.
Die Liniendisziplin ist auch dafür verantwortlich , das SIGINT
Signal an die Vordergrundprozessgruppe des Terminals zu senden, wenn es ein ^C
Zeichen auf der Masterseite usw. empfängt .
Viele interaktive Terminalanwendungen deaktivieren die meisten Funktionen dieser Zeilendisziplin, um sie selbst zu implementieren. Beachten Sie jedoch in jedem Fall, dass das Terminal ( xterm
) wenig damit zu tun hat (es sei denn, Sie zeigen an, was angezeigt werden soll).
Und es kann nur eine Sitzung pro Prozess und pro Endgerät geben. An eine Sitzung kann ein steuerndes Terminal angeschlossen sein, muss es aber nicht (alle Sitzungen beginnen ohne Terminal, bis sie eines öffnen). Öffnen xterm
Sie in dem Prozess, in dem die Shell ausgeführt werden soll, in der Regel eine neue Sitzung (und trennen Sie sich daher von dem Terminal, von dem aus Sie gestartet haben xterm
), /dev/pts/x
die neu erstellte Sitzung, indem Sie dieses Endgerät an die neue Sitzung anschließen. Anschließend wird Ihre Shell in diesem Prozess ausgeführt, sodass Ihre Shell zum Sitzungsleiter wird. Ihre Shell oder eine beliebige interaktive Shell in dieser Sitzung wird normalerweise mit Prozessgruppen und jonglieren tcsetpgrp()
, um die Vordergrund- und Hintergrundjobs für dieses Terminal festzulegen.
In Bezug auf die Informationen, die von einem Endgerät mit einer Tty-Disziplin (seriell oder pty) gespeichert werden , stty
zeigt der Befehl in der Regel diese Informationen an und ändert sie. Konfiguration aller Disziplinen: Terminal-Bildschirmgröße, Lokal, Eingabe-Ausgabe-Flags, Einstellungen für Sonderzeichen (wie ^ C, ^ Z ...), Eingabe- und Ausgabegeschwindigkeit (nicht relevant für ptys). Das entspricht den tcgetattr()
/ tcsetattr()
Funktionen, die unter Linux den TCGETS
/ TCSETS
ioctls zugeordnet sind, und TIOCGWINSZ
/ TIOCSWINSZ
für die Bildschirmgröße. Sie können argumentieren, dass die aktuelle Vordergrundprozessgruppe eine andere im Endgerät gespeicherte Information ( tcsetpgrp()
/ tcgetpgrp()
, TIOC{G,S}PGRP
ioctls) oder der aktuelle Eingabe- oder Ausgabepuffer ist.
Beachten Sie, dass die im Endgerät gespeicherten Informationen zur Bildschirmgröße möglicherweise nicht der Realität entsprechen. Der Terminal-Emulator legt dies normalerweise fest (über das gleiche ioctl in der Master-Größe), wenn die Fenstergröße geändert wird. Es kann jedoch zu Synchronisationsstörungen kommen, wenn eine Anwendung das ioctl auf der Slave-Seite aufruft oder wenn die Größenänderung nicht übertragen wird (falls zutreffend) eine SSH - Verbindung , die durch eine anderen PTY hervorgebracht impliziert , sshd
wenn ssh
die ignoriert SIGWINCH
zum Beispiel). Einige Terminals können auch über Escape-Sequenzen nach ihrer Größe abgefragt werden, sodass eine Anwendung dies abfragen und die Leitungsdisziplin mit diesen Informationen aktualisieren kann.
Für weitere Informationen können Sie einen Blick auf die haben termios
und tty_ioctl
man - Seiten auf Debian zum Beispiel.
Um mit anderen Liniendisziplinen zu spielen:
Emulieren Sie eine Maus mit einem Pseudo-Terminal:
socat pty,link=mouse fifo:fifo
sudo inputattach -msc mouse # sets the MOUSE line discipline and specifies protocol
xinput list # see the new mouse there
exec 3<> fifo
printf '\207\12\0' >&3 # moves the cursor 10 pixels to the right
Oben wird die Masterseite des Pty durch socat auf einer Named Pipe ( fifo
) abgeschlossen. Wir verbinden dieses FIFO mit einem Prozess (der Shell), der 0x87 0x0a 0x00 schreibt, was im Maussystemprotokoll bedeutet no button pressed, delta(x,y) = (10,0)
. Hier emulieren wir (die Shell) kein Terminal, sondern eine Maus. Die 3 Bytes, die wir senden, dürfen nicht von einer Anwendung des Terminalgeräts gelesen (möglicherweise transformiert) werden ( mouse
darüber befindet sich ein Symlink, der von socat
einem /dev/pts/x
Gerät erstellt wurde). , sind aber als Mauseingabeereignis zu interpretieren.
Erstellen Sie eine SLIP-Schnittstelle:
# on hostA
socat tcp-listen:12345,reuseaddr pty,link=interface
# after connection from hostB:
sudo ldattach SLIP interface
ifconfig -a # see the new interface there
sudo ifconfig sl0 192.168.123.1/24
# on hostB
socat -v -x pty,link=interface tcp:hostA:12345
sudo ldattach SLIP interface
sudo ifconfig sl0 192.168.123.2/24
ping 192.168.123.1 # see the packets on socat output
Oben wird die serielle Verbindung socat
als TCP-Socket zwischen HostA und HostB emuliert. Die SLIP-Leitungsdisziplin interpretiert die über diese virtuelle Leitung ausgetauschten Bytes als SLIP-gekapselte IP-Pakete zur Übermittlung an die sl0
Schnittstelle.
cat /dev/ptmx &
which ein neues Pty zu öffnen, aber es gibt dann keinen Prozess, den ich damit verknüpfen kann. Wie würden Sie es verwenden? Zweitens habe ich es mit versuchtecho "1" >/dev/ptmx
, aber das hat nichts gebracht ... Warum interessiert mich das? Beacause oft , wenn man eine Verbindung der Ferne überssh
(zum Beispiel), erhalten SiePTY allocation request failed
oderNo controlling tty: open /dev/tty
Fehler, die Auftragssteuerung verhindert. Es wäre schön, diese besser zu verstehen.pty
Einzelheiten finden Sie auf Ihrer Manpage.physical term
----tty
----bash
auf Terminals undpty(m)
----tty
----pty(s)
----bash
auf Terminalemulatoren ist? War dietty
Disziplin verantwortlich für Echo zu Zeichen auf physischen Terminal? 2. Ist es das Terminal-Emulator-Programm, das eine Verbindung zur Tastatur / zum Bildschirm herstellt, um die Eingabe zu verwalten? 3. Nach meinem Verständnis haben Sie gesagt, dass die Zeilenpufferung von Bash-Befehlen / allen Terminal-Eingaben durchtty
Zeilendisziplin anstelle von E / A-Puffern von CI / O-Funktionen erfolgt. Ist das richtig?Bearbeiten: Seit dieser Antwort habe ich einen speziellen Artikel in meinem Blog geschrieben, für Leute, die sich für mehr Details interessieren würden.
Nach vielem Lesen habe ich das verstanden.
/dev/ptmx
ordnet den Slave-Teil nicht zu : Er ordnet den "Pseudo-Terminal-Master-Teil" zu. / dev / ptmx ist kein Master-Pseudo-Terminal : Es ist ein Pseudo-Terminal-Master-Multiplexer . Es wurde mit dem PTY-Standard Unix98 erstellt, um Race-Bedingungen bei der Zuweisung des Master-Pseudoterminals ( Quelle ) zu vermeiden .Der Masterteil (ptm) des Pseudoterminals ist im Dateisystem nicht dargestellt. Es wird durch einen Dateideskriptor dargestellt.
Der Slave - Teil (pts) wird durch eine Datei repräsentiert in
/dev/pts/N
denenN
eine Zahl ist .Das PTS wird erhalten aus dem PTM durch den aufeinanderfolgenden Anruf von
grandpt
,unlockpt
,ptsname
. ( Quelle )Das ptm ersetzt den AUR-Treiber für die Kommunikation mit dem Gerät und die Line Edition. Es emuliert also in keiner Weise ein Terminal, sondern bietet die Funktion der Zeilenbearbeitung und eine Möglichkeit zur Visualisierung und Kommunikation mit pts. ( Quelle )
Hier ist ein Diagramm eines TTY, der an ein Hardwaregerät angeschlossen war
Und hier ist ein Diagramm eines tty, das mit einem ptm verbunden ist
Die ptm-Datei verarbeitet andere Ioctl-Argumente (ISPTM, UNLKPT, TIOCREMOTE, TIOCSIGNAL) als die pts.
Prozesse interagieren mit Geräten durch Aktionen, die an einer virtuellen Datei ausgeführt werden (Lesen, Schreiben, Ioctl ..). Die Datei selbst existiert nicht und der Treiber verwendet die Datei, um Aktionen auszulösen, wenn Lese- oder Schreibmethoden aufgerufen werden. (Informationen zu Treibern finden Sie im Anhang)
Ein TTY definiert einen präzisen Weg, um mit ihm zu interagieren. Prozesse schreiben und lesen vom Gerät und erwarten dasselbe Verhalten, unabhängig davon, welche Art von TTY implementiert ist.
Die Punkte verhalten sich wie ein TTY-Treiber. Die Lese- und Schreibmethode wird verwendet, um das Verhalten des TTY-Treibers zu implementieren. Da es kein echtes Gerät zum Senden der Daten gibt, wird ein Stream-Paar erstellt, und der ptm implementiert eine Lesefunktion zum Lesen der von pts an den Stream gesendeten Daten und eine Schreibfunktion zum Senden von Daten an den verfügbaren Stream wann die pts es lesen werden.
Denken Sie daran, dass die Datei, die ein Gerät darstellt, keine klassische Datei ist. Wenn Sie sehen
xterm
möchten, was in die Datei geschrieben wurde, können Sie sie nicht einfach öffnen und lesen, da diese Funktionen hier ein völlig anderes Verhalten haben.Ich glaube nicht, die Sitzungs-ID wird durch den ersten Prozess definiert, der die PTS anfügt (Bash im Allgemeinen), und ich sehe keine Möglichkeit, eine weitere Sitzung zu erstellen und an dieselben PTS anzuhängen. Vielleicht könnte so ein Tool
socat
das tun?Die Punkte speichern 2 Kategorien von Informationen in Bezug auf das Terminal, mit dem sie kommunizieren: das
Terminfo
und dasTermcap
. In der Regel basieren viele Terminalemulatoren auf einer Bibliothek, die Termcap-Informationen für sie verwaltet (die beispielsweise alle Funktionswerte für die Emulation eines VTX100 bereitstellen). Ein Beispiel für eine solche Bibliothek ist libvte . Bearbeiten (sieheStephane Chazelas Kommentar): Die Terminalfähigkeiten werden nicht von den Pkt gespeichert.Nebengebäude
quelle
Hier ist ein Schema, das ich vor einiger Zeit gemacht habe, wie es
sshd
funktioniert. Es geht nicht um die Funktionsweise von Liniendisziplin und anderen Dingen, sondern um die Darstellung, wer mit was interagiert:quelle
-T
, was der Mann sagt, dass es die Zuweisung von Pseudoterminals deaktiviert. zB:ssh -T emasculateur@localhost "sleep 10"
dannps aux|grep sleep
zeigt dies:emasculateur 21826 0.0 0.0 23032 3728 ? Ss 02:49 0:00 zsh -c sleep 10
In diesem Fall wo schreibt bashstdout
undstderr
? Ich hoffe meine Frage macht Sinn./dev/null
für einen normalen Daemon nur nach Wunsch funktionieren, aber nicht sicher sind. Siehe auch: serverfault.com/questions/593399/…nohup
oderscreen
/ gestartet wurdentmux
.man pts
sagt:Über
/dev/pts/X indexing
:Jedes X ist eine Sitzung, die Sie öffnen, also müssen die Slaves indizieren.
Über
TeteType (/dev/ttyN
):Es ist eine echte Konsole, die von Ihrem Boot-System generiert wurde, z
sysV
.Über den Grund, warum ein Slave einen Master installiert hat: http://commons.wikimedia.org/wiki/File:Termios-script-diagram.png
quelle