Wie nimmt `less` Daten aus stdin, während es weiterhin in der Lage ist, Befehle vom Benutzer zu lesen?

47

Wie die meisten von Ihnen es schon oft getan haben, ist es praktisch, Langtext anzuzeigen, indem Sie Folgendes verwenden less:

some_command | less

Jetzt ist sein Standard mit einer Pipe (FIFO) verbunden. Wie kann es noch Befehle wie up / down / quit lesen?

iBug
quelle
15
lessLiest die anzuzeigenden Daten von stdin und liest Befehle vom tty. Sie sind verschiedene Dinge.
William Pursell
2
@ WilliamPursell Ja, ich weiß. Aber es gibt nur einen Standardeingabestream, oder?
iBug
4
Ja, es gibt einen Eingabestream und einen Tty. lessLiest Daten aus stdin und Befehle aus dem tty.
William Pursell

Antworten:

52

Liest, wie von William Pursell erwähnt , lessdie Tastatureingaben des Benutzers vom Terminal. Es öffnet sich explizit /dev/ttydas steuernde Terminal; Das gibt ihm einen von der Standardeingabe getrennten Dateideskriptor, aus dem er die interaktiven Eingaben des Benutzers lesen kann. Es kann bei Bedarf gleichzeitig Daten von seiner Standardeingabe lesen, um sie anzuzeigen. (Es könnte auch schreiben direkt an das Endgerät , falls erforderlich.)

Sie können dies durch Laufen sehen

some_command | strace -o less.trace -e open,read,write less

Bewegen Sie sich durch die Eingabe, beenden Sie sie lessund sehen Sie sich den Inhalt von less.trace: an. Sie sehen, dass sie geöffnet /dev/ttyist und lesen sowohl den Dateideskriptor 0 als auch denjenigen, der beim Öffnen zurückgegeben wurde /dev/tty(wahrscheinlich 3).

Dies ist gängige Praxis für Programme, die sicherstellen möchten, dass sie vom Terminal lesen und auf das Terminal schreiben. Ein Beispiel dafür ist SSH, zB wenn es nach einem Passwort oder Passwort fragt.

Wie von schily erklärt, wird , wenn es nicht geöffnet werden kann, von seinem Standardfehler gelesen (Dateideskriptor 2). Die Verwendung von wurde in Version 177 eingeführt, die am 2. April 1991 veröffentlicht wurde./dev/ttylessless/dev/tty

Wenn Sie versuchen , laufen cat /dev/tty | less, wie vorgeschlagen von Hagen von Eitzen , lesswird in der Öffnung gelingt /dev/ttyaber nicht jede Eingabe von ihr bis bekommen catschließt es. Sie sehen also den Bildschirm leer und nichts anderes, bis Sie drücken CtrlC, um zu töten cat(oder auf andere Weise zu töten ); Anschließend lesswird angezeigt, was Sie während catder Ausführung eingegeben haben , und Sie können es steuern.

Stephen Kitt
quelle
4
@HagenvonEitzen Ihr Computer wird explodieren! Es ist so, wie Kirk und Spock Mudds Androiden zum Absturz gebracht haben.
Barmar
7
@HagenvonEitzen Wow. Eine doppelt nutzlose Verwendung von Katze . Ich bin beeindruckt.
Andrew Henle
8
@grawity Ich denke, Andrews Punkt ist, cat blah |dass er durch ersetzt werden kann < blah, und selbst das ist in diesem Fall unnötig, da es auch less blahfunktioniert ( na ja less -f /dev/tty). Das Auslesen /dev/ttyist jedoch ein Sonderfall, und alle drei Varianten ( cat /dev/tty | less, less < /dev/ttyund less -f /dev/tty) führen zu unterschiedlichen Ergebnissen.
Stephen Kitt
1
Zeigt / dev / tty irgendwie immer an die richtige Stelle? Ich würde denken, Sie müssten / dev / ptsX normalerweise verwenden?
StarWeaver
2
@StarWeaver sehen diese Frage über den Unterschied zwischen /dev/ttyund /dev/pts/....
Stephen Kitt
26

UNIX bietet zwei Methoden zum Lesen von Benutzereingaben, während stdin umgeleitet wurde:

  • Die ursprüngliche Methode ist, aus stderr zu lesen . Stderr ist zum Schreiben und Lesen geöffnet und dies wird in POSIX noch erwähnt.

  • In späteren UNIX-Versionen (um 1979) wurde eine /dev/ttyTreiberoberfläche hinzugefügt , mit der die Steuerung eines Prozesses geöffnet werden kann. Da es Prozesse ohne Steuerung gibt, ist es möglich, dass ein Öffnungsversuch /dev/ttyfehlschlägt. Freundlich geschriebene Software greift daher auf die ursprüngliche Methode zurück und versucht dann, aus stderr zu lesen.

schily
quelle
11
Aus stderr lesen? Etwas Neues gelernt.
iBug
1
Ich bin froh, dass sich jemand an die alten Wege erinnert.
Joshua
3
Wird stderr zum Lesen verwendet, weil es mit der geringsten Wahrscheinlichkeit umgeleitet wurde? Ich sehe keinen anderen Unterschied zwischen ihm und stdout (oder aus diesem Grund vor der Umleitung).
Strg-Alt-Delor
4
Ja, da dies der Dateideskriptor ist, der die geringste Chance hat, umgeleitet zu werden.
Schily
@ ctrl-alt-delor: Es war / ist typisch, dass Shells mit stdin, stdout und stderr ausgeführt wurden, die alle dup()Lizenzen derselben Dateibeschreibung waren, jedoch alle auf dem tty geöffnet waren. (Anscheinend erfordert oder schlägt POSIX immer noch vor (diese Antwort sagt nichts), dass stderr eine Lese- / Schreib-FD ist, die nicht mit so etwas wie geöffnet wird open("/dev/ttyS0", O_WRONLY). Das Lesen von stderr würde in diesem Fall fehlschlagen.)
Peter Cordes