Was ist in / dev / pts-Dateien gespeichert und können wir sie öffnen?

73

Meines Wissens nach werden /dev/ptsDateien für SSH- oder Telnet-Sitzungen erstellt.

user2720323
quelle
6
echo Hello > /dev/pts/1... Sehen Sie, was passiert, es ist Ihr Terminal.
Sepahrad Salour
1
@SepahradSalour muss man die pts Nummer seinem Kontext anpassen. Mein SSHD hat / dev / pts / 30 für meine Sitzung verwendet.
Gab 是 好人
2
@Gab 是 好人 Mit dem Befehl können Sie den Standort Ihres aktuellen Terminals ermitteln tty.
JeromeJ

Antworten:

110

Nichts ist in gespeichert /dev/pts. Dieses Dateisystem lebt rein im Speicher.

Einträge in /dev/ptssind Pseudo-Terminals (kurz Pty). Unix-Kernel haben einen allgemeinen Begriff von Terminals . Ein Terminal bietet Anwendungen die Möglichkeit, Ausgaben anzuzeigen und Eingaben über ein Terminalgerät zu empfangen . Ein Prozess kann ein steuerndes Terminal haben - für eine Textmodus-Anwendung interagiert es auf diese Weise mit dem Benutzer.

Terminals können entweder Hardware-Terminals ("tty", kurz für "Teletype") oder Pseudo-Terminals ("pty") sein. Hardware-Terminals werden über eine Schnittstelle wie eine serielle Schnittstelle ( ttyS0,…) oder USB ( ttyUSB0,…) oder über einen PC-Bildschirm und eine Tastatur ( tty1,…) angeschlossen. Pseudoterminals werden von einem Terminalemulator bereitgestellt, bei dem es sich um eine Anwendung handelt. Einige Arten von Pseudoterminals sind:

  • GUI-Anwendungen wie xterm, gnome-terminal, konsole, ... wandeln Tastatur- und Mausereignisse in Texteingabe um und zeigen die Ausgabe grafisch in einer bestimmten Schriftart an.
  • Multiplexer-Anwendungen wie Bildschirm- und Multiplexer-Relais-Ein- und -Ausgang von und zu einem anderen Terminal, um Textmodus-Anwendungen vom eigentlichen Terminal zu entkoppeln.
  • Remote-Shell-Anwendungen wie sshd, telnetd, rlogind usw. leiten die Ein- und Ausgabe zwischen einem Remote-Terminal auf dem Client und einem Pty auf dem Server weiter.

Wenn ein Programm ein Terminal zum Schreiben öffnet, wird die Ausgabe dieses Programms auf dem Terminal angezeigt. Es ist üblich, dass mehrere Programme gleichzeitig auf einem Terminal ausgegeben werden. Dies kann jedoch manchmal verwirrend sein, da nicht erkennbar ist, welcher Teil der Ausgabe von welchem ​​Programm stammt. Hintergrundprozesse, die versuchen, auf ihr steuerndes Terminal zu schreiben, können durch ein SIGTTOU-Signal automatisch angehalten werden .

Wenn ein Programm ein Terminal zum Lesen öffnet, wird die Eingabe des Benutzers an dieses Programm übergeben. Wenn mehrere Programme von demselben Terminal lesen, wird jedes Zeichen unabhängig an eines der Programme weitergeleitet. Dies wird nicht empfohlen. Normalerweise liest zu einem bestimmten Zeitpunkt nur ein einziges Programm aktiv vom Terminal. Programme, die versuchen, von ihrem steuernden Terminal zu lesen, während sie sich nicht im Vordergrund befinden, werden automatisch durch ein SIGTTIN-Signal angehalten .

Führen Sie zum Experimentieren ttyein Terminal aus, um zu sehen, um welches Terminal es sich handelt. Sagen wir es ist /dev/pts/42. Führen Sie in einer Shell in einem anderen Terminal Folgendes aus echo hello >/dev/pts/42: Die Zeichenfolge hellowird auf dem anderen Terminal angezeigt. Führen Sie nun cat /dev/pts/42das andere Terminal aus und geben Sie es ein. Um diesen catBefehl zu beenden (was die Verwendung des anderen Terminals erschwert), drücken Sie Ctrl+ C.

Das Schreiben an ein anderes Terminal ist gelegentlich nützlich, um eine Benachrichtigung anzuzeigen. Zum Beispiel macht der writeBefehl das. Das Lesen von einem anderen Terminal wird normalerweise nicht durchgeführt.

Gilles
quelle
Entweder verstehe ich falsch, was Sie sagen wollen, oder Ihre Informationen sind nicht korrekt. Hintergrundprozesse, die in das Terminal schreiben, führen nicht zu einem SIGTTIN. Es können auch nicht mehrere Programme gleichzeitig vom Terminal gelesen werden (Ihre Aussage, dass "jedes Zeichen unabhängig weitergeleitet wird"). Es kann immer nur ein Programm vom Terminal lesen, und der Versuch eines Hintergrundprogramms, von diesem Terminal aus zu lesen, führt zu einem SIGTTIN. Dies ist der einzige Fall, in dem SIGTTIN automatisch gesendet wird.
Patrick
Sie können auch nicht von einem anderen Terminal lesen. Dies wäre eine erhebliche Sicherheitslücke, da Sie Daten abfangen könnten. Sie können stracedas Programm lesen, aber das ist es.
Patrick
4
@Patrick Hintergrundprozesse, die auf das Terminal schreiben, erhalten SIGTTOU, das war ein Tippfehler. Mehrere Programme können gleichzeitig vom Terminal lesen (probieren Sie es aus und sehen Sie, wie ich es im nächsten Abschnitt beschreibe; Sie müssen es von einem Prozess aus tun, dessen steuerndes Terminal nicht dieses Terminal ist). Ja, Sie können von einem anderen Terminal aus lesen, solange es Ihnen gehört. Warum ist das Ihrer Meinung nach unmöglich?
Gilles
Hintergrundprozesse, die in das Terminal schreiben, erhalten SIGTTOU nur, wenn das tostoptty-Flag gesetzt ist. Dieses Flag ist standardmäßig nicht gesetzt. Und ich stehe auf das Lesen von einem anderen TTY korrigiert. Ich habe es ausprobiert und es funktioniert, aber es wird pro Lesevorgang und nicht pro Zeichen ausgeführt (wenn Sie an einer Shell-Eingabeaufforderung sitzen, sind sie mit den Shells identisch, die jeweils 1 Zeichen lesen). Es könnte gut sein, diesen Punkt zu klären, da ich Ihre Antwort jetzt so interpretiert habe.
Patrick
2
@Patrick Sicher, ein readAufruf gibt nur aufeinanderfolgende Zeichen zurück (oder eher Bytes, sollte ich sagen), aber die Anwendung hat keine Kontrolle darüber, wie viele Bytes ein readAufruf zurückgibt, daher ist es nicht besser.
Gilles
18

Die Dateien in /dev/ptssind "pseudo-ttys". Sie ähneln in gewissem Maße Named Pipes, ahmen aber auch alte serielle Anschlussklemmen wie VT-100 nach. Pseudo-ttys übernehmen die Übertragung von Bytes von der Tastatur zum Programm und vom Programm zum Ausgabegerät, was sich einfach anhört. Aber das beantwortet Ihre explizite Frage: Der Kernel speichert /dev/pts/0zum Beispiel nichts darin . Nur Ströme von Bytes von stdout eines mit der Pseudotty verbundenen Programms gehen ein, und Programme, deren stdin mit derselben Pseudotty verbunden ist, lesen diese Bytes.

Pseudo-ttys fügt diesen Byteströmen auch eine Indirektionsebene hinzu. Der Kernel kann Bytes auf spezielle Werte wie "Control-C" oder "Control-D" oder "Control-U" prüfen (die alle konfigurierbar sind, siehe man stty) und ein SIGINT senden, das Dateiende auf stdin setzen oder löschen eine Zeile am Eingang. Irgendwo gibt es auch eine Pufferfunktion, so dass mein "nichts speichern" etwas falsch ist, aber nur um ein paar Kilobyte.

Der Kernel kann die Bytewerte bei der Ausgabe überprüfen und beispielsweise eine neue Zeile (ASCII-Zeilenvorschub, LF oder "\n") in zwei Bytes, Wagenrücklauf und Zeilenvorschub (CRLF oder "\r\n") oder die für eine serielle Terminalhardware erforderlichen Bytes umwandeln . Die Indirektion einer Pseudotty ermöglicht die Unabhängigkeit von Hardware.

Pseudo-ttys erlauben auch alle "eingestellten Baudraten", "eingestellte Parität" usw. ioctl()Systemaufrufe und tun wahrscheinlich nichts mit ihnen. Auf diese Weise können Programme, die zu Zeiten von VT-100s, ADM-3 und Wyse geschrieben wurden, fehlerfrei weiterarbeiten. Software, der Pseudo-tty-Gerätetreiber, verhält sich wie Hardware.

Pseudo-ttys können von sshdund verwendet werden telnet, sie werden jedoch auch zwischen einem Terminal-Emulator (wie xtermoder rxvt) und der Shell verwendet, die normalerweise im xterm ausgeführt wird.

Linux und viele Unixe haben Pseudo-tty. Plan 9 geht nicht. Pseudo-ttys sind ein kleines Relikt aus der Zeit der seriell verkabelten Hardware-Terminals.

Bruce Ediger
quelle
13

/dev/ist ein spezielles Verzeichnis für Gerätedateien. Dies sind Abstraktionen, keine echten Dateien auf der Festplatte. Das Verzeichnis wird beim Booten ausgefüllt und kann geändert werden, um vorhandene Geräteschnittstellen widerzuspiegeln, die vom Kernel und einem Userspace-Daemon erstellt und zerstört werden udevd.

Viele der so dargestellten Geräte sind virtuell. Dies schließt die Einträge in ein /dev/pts, bei denen es sich um Konsolengeräte handelt. Aus diesem Grund wird eine für Remotesitzungen erstellt. Sie werden auch erstellt, wenn Sie ein lokales GUI-Terminal öffnen.

Sie können sie als Dateien öffnen, obwohl sie nicht von großem Nutzen sind. Um den /dev/ptsKnoten zu ermitteln, mit dem Ihre Shell verbunden ist, verwenden Sie tty:

> tty
/dev/pts/4

Wechseln Sie nun zu einer anderen Konsole und versuchen Sie Folgendes:

> echo "duck!" > /dev/pts/4

Klug. Versuchen Sie jetzt:

> cat /dev/pts/4

Versuchen Sie dann, die Shell unter / dev / pts / 4 zu verwenden. Du steckst fest, bis du das catauf der anderen Seite beendest, aber das meiste, was du auf pts / 4 tippst, wird durchgehen (z. B. "Hallo Welt", mit dem ich hlauf pts / 4 und ello wordauf der catKonsole gelandet bin ).

Ich vermute hier, dass das Gerät Eingaben von der Shell nimmt und über das System ausgibt, was bedeutet, dass Dinge auf dem Bildschirm landen - die Shell befasst sich nicht mit Hardware, sondern mit dem System. Probieren Sie es aus strace bash(und schauen man straceSie sich an, wenn Sie nicht wissen, was es ist); Sie erhalten eine vorläufige Flut von Anrufen, wenn die Bash startet. Schlagen Sie jetzt die Tasten:

read(0, "h", 1)                         = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "h", 1h)                        = 1
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
read(0, "e", 1)                         = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "e", 1e)                        = 1
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
read(0, "y", 1)                         = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "y", 1y)                        = 1
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0

Für jeden eingegebenen Buchstaben wird von der Standardeingabe gelesen und von der Standardausgabe geschrieben. Aber womit ist der Standard der Shell verbunden? Probieren straceSie jetzt Ihr GUI-Terminal aus - Sie müssen den Namen herausfinden, wenn Sie ihn nicht kennen, z. B. unter KDE konsole, und GNOME hat den gnome-terminal, glaube ich. Die Ausgabe davon straceist wahrscheinlich kryptischer - meine hat viel poll()und recvfrom(). Ich sehe keine Schreibvorgänge, aber wenn Sie jetzt den catTrick von einem anderen Terminal aus ausführen, werden Sie feststellen, dass die von cat gelesenen Tastenanschläge bei der Ausgabe von strace überhaupt keine Reaktion hervorrufen - das Terminal ist nicht ' Ich empfange sie nicht. Daher konkurrieren die GUI-Terminal-App und die Katze, um von demselben Gerät zu lesen, in das die Shell ausgibt.

Goldlöckchen
quelle
Was ist die Verwendung von 'cat / dev / pts / 4', wenn wir nicht weiterkommen und warum wir nicht weiterkommen, während wir diesen Befehl ausführen?
User2720323
Ich habe ein paar Absätze hinzugefügt, um dies zu erklären.
Goldlöckchen