
Wenn Sie cal unter Linux ausführen, wird die Ausgabe für den aktuellen Monat in umgekehrter Reihenfolge angezeigt, wobei der aktuelle Tag hervorgehoben wird. Wenn ich diese Ausgabe an hexdump -c sende, erhalte ich einige interessante Ergebnisse:
0000000 N o v e m b e r 2 0 1 6
0000010 \n S u M o T u
0000020 W e T h F r S a \n
0000030 1 2 _ \b _ \b 3
0000040 4 5 \n 6 7
0000050 8 9 1 0 1 1 1 2 \n
0000060 1 3 1 4 1 5 1 6 1 7 1
0000070 8 1 9 \n 2 0 2 1 2 2
0000080 2 3 2 4 2 5 2 6 \n 2 7
0000090 2 8 2 9 3 0
00000a0 \n
00000b0 \n
00000bc
Wie Sie sehen, wird vor der für heute hervorgehobenen „3“ eine unsichtbare Sequenz aus _\b _\b gedruckt. _ ist ein Unterstrich (5F in ASCII-Hex) und \b ist Strg-H oder 08 in ASCII-Hex. Was ist das? Ich weiß, dass es viele obskure Terminalcodes gibt, aber ich würde erwarten, dass hier etwas Standardmäßigeres wie \e[7m verwendet wird. Noch seltsamer ist, dass ich das gleiche Verhalten von cal nicht reproduzieren kann, indem ich die gleichen Zeichen mit Standard-Printf-Funktionen wie einem dieser Befehle ausdrucke:
/usr/bin/printf "1 2 _\b _\b3 4 5\n"
/usr/bin/printf "1 2 _^H _^H3 4 5\n"
Wobei ^H durch Drücken von Strg-V Strg-H erzeugt wird. Aber keines davon erzeugt dieselbe inverse Videoausgabe wie cal. Ich habe sogar versucht, ein kleines C-Programm zu schreiben, um dies zu tun. Ich habe es auch mit echo -e versucht. Das Interessante ist, dass es zwar das Video im Terminal nicht umkehrt, aber wenn ich die Ausgabe von less -R weiterleite, ändert es seine Farbe in Gelb und unterstreicht es. Auf anderen Terminals, die ich versucht habe, unterstreiche ich es nur. Es sieht fast wie Überschreiben aus, aber wenn ich ein anderes Zeichen als _ verwende, funktioniert es nicht, was mich glauben lässt, dass _\b eine einzelne Codefolge ist. Und wie wird das Video für dieses Zeichen dann umgekehrt?
Irgendwelche Erkenntnisse dazu?
Auf der Manpage steht, dass die Ausgabe von cal eine bitweise kompatible Version des ursprünglichen Unix-Befehls cal sein soll. Ich kann also nur annehmen, dass es sich um alten Code handelt.
Antwort1
Es scheint fast wie ein Überschlag
Genau das ist es. Wie besprochen beiWarum gibt es auf einer 80-Spalten-Konsole 11 Tabstopps?, hilft es, sich die Funktionsweise mechanischer Schreibmaschinen in Bezug auf Unix-Terminals vorzustellen. In diesem Fall _
ist die Sequenz BS (das Backspace-Zeichen) vor einem Zeichen eine Konvention, die verwendet wird, um die Unterstreichung dieses Zeichens anzuzeigen, da auf einigen Terminals Text auf diese Weise unterstrichen wird. Eine alternative Steuersequenz ist BS _
nach dem Zeichen. Auf den ursprünglichen Terminals war es natürlich egal, was was überstrichen hat. Auf modernen Videoterminals „gewinnt“ das zuletzt geschriebene Zeichen und löscht vorherige Daten. Daher ist die _
BS <Zeichen>Reihenfolge wird bevorzugt.
FreeBSD ncal
, und das ist dieses Programm, verfügt über zwei Betriebsarten, wenn es um die Hervorhebung geht.
- Wenn die Ausgabe ein Terminal ist, sucht es in der Termcap-Datenbank nach den
so
undse
-Sequenzen für den aktuellen Terminaltyp und gibt diese auf beiden Seiten des hervorgehobenen Textes aus. (Es gibt tatsächlich einen Fehler im Code, der dies verursacht. Er hat damit zu tun, dass ein Puffer auf dem Stapel seinen Gültigkeitsbereich verlässt und sein Inhalt später verwendet wird. Den scheint niemand bemerkt zu haben.) - Wenn die Ausgabe kein Terminal ist, wird der Text ausgegeben, wobei jedem hervorzuhebenden Zeichen eine
_
BS-Sequenz vorangestellt ist.
Sie können dies nicht replizieren, indem Sie eine _
BS-Sequenz an Ihr Terminal senden, es sei denn (natürlich) Ihr Terminal ist eines der Terminals, bei denen Dinge auf diese Weise unterstrichen werden. Dies ist bei Terminalemulatoren nicht der Fall und mit ziemlicher Sicherheit auch nicht bei den Terminals oder Terminalemulatoren, die Sie hier verwenden.
Sie können jedochFilterText, der diese Konvention verwendet, durch das ul
Programm, das diese und mehrere andere schreibmaschinenähnliche Konventionen erkennt und sie in die tatsächlichen Steuersequenzen für das Terminal übersetzt und sie in der Termcap-Datenbank nachschlägt. Sie können die Ausgaben Ihrer printf
Befehle ul
auch durch filtern.
Auf anderen Terminals, die ich ausprobiert habe, wird es nur hervorgehoben.
Ironischerweise ist das Filtern der Nicht-Terminal-Modus-Ausgabe ncal
durch das ul
Programm tatsächlich etwas besser als das ncal
Schreiben von Terminal-Steuersequenzen selbst. Während ncal
verwendet das Programm die Ausgabe des Terminalsauffallenul
versucht , die tatsächlicheunterstreichenModus (falls vorhanden) beim Übersetzen der _
BS-Sequenz. Wie im Termcap-Handbuch erklärt wird, kann der Hervorhebungsmodus alles sein, was für das Terminal geeignet ist (einschließlich Fettdruck, invertiertes Video oder Farben) und muss nicht unbedingt Unterstreichung sein. Auf einem Ihrer Terminals ist es eindeutig eine Kombination aus Unterstreichung und Farbänderung.
Darüber hinaus ul
kommt es auch mit Terminals zurecht, die keine unterstrichenen Start-/Endsequenzen haben, aber unterstrichene letzte Zeichenfolgen. Ironischerweise ul
kommt es zurecht, wenn Ihr Terminalwirklich istEines, das dies dadurch unterstreicht, dass _
nach jedem Zeichen „BS“ steht, wohingegen ncal
es damit nicht klarkommt.
ul
Und hat natürlich nicht ncal
den Pufferbehandlungsfehler. ☺
Wenn ich die Ausgabe weiterleite
less -R
, ändert sich die Farbe in Gelb und es wird unterstrichen.
Wie Sie bemerkt haben, less
versteht das Programm _
BS-Sequenzen und verarbeitet sie ähnlich wie das ul
Programm selbst. Es ist nicht ganz dasselbe. ul
kann Sequenzen mit mehreren _
und BS-Zeichen verarbeiten und kann auch ähnliche Sequenzen für Fettdruck verarbeiten. less
kann dies nicht. Vergleichen Sie, was Sie von diesen beiden sehen:
/usr/bin/printf "1 2 ______\b\b\b\b\b\b\b 3 _\b4. \b\b\b45 6\n" | ul
/usr/bin/printf "1 2 ______\b\b\b\b\b\b\b 3 _\b4. \b\b\b45 6\n" | weniger
zurück in die gute alte Zeit
Leider sind das immer noch „die guten alten Zeiten“. Lassen Sie sich nicht einreden, dass dies heutzutage kaum noch genutzt wird.
Es steht zwar nicht im Handbuch, aber der Quellcode ul
weist darauf hin, dass er versucht, die Steuersequenzverarbeitung eines Teletype Model 37 zu implementieren, weil "das die nroff
Ausgabe ist". Der GNU-Ersatz für das ursprüngliche Unix- nroff
Programm, geschrieben lange nachdem Terminals ausgefallene Funktionen wie Farben, Fettdruck und Kursivschrift erhalten hatten, ist in der Lage,ECMA-48Steuersequenzen für Farben, Fettdruck und Kursivschrift. Das tut es tatsächlichim Normalfall.
nroff
und sein GNU-Ersatz werden zum Formatieren von Handbuchseiten für die Anzeige auf Ihrem Terminal verwendet. Traurigerweise und ironischerweise begannen Leute etwa 10 Jahre nach seiner Erstellung damit, das GNU-Tool zu schwächen, sodass es die alten Teletype Model 37-Sequenzen von 1968 statt der „neuen“ ECMA-48-Steuersequenzen von 1976 (sic!) generierte. Sie erstellten man
invoke groff
mit Optionen, die sein Standardverhalten änderten, und fügten nicht dokumentierte Dateien hinzu, die zusätzliche ditroff-Ausgaben erzwangen.
Jedes Mal, wenn Sie eine Handbuchseite auf Ihrem Terminal lesen, läuft das Handbuchsystem, groff
das den Quelltext des Handbuchs sorgfältig in einen Ausgabezeichenstrom mit diesen alten Steuersequenzen des Teletype Model 37 umwandelt, die less
wiederum more
in die Steuersequenzen Ihres Terminals umgewandelt werden.
Weiterführende Literatur
- Jonathan de Boyne Pollard (2016). Kursivschrift und Farbe in Handbuchseiten auf einem virtuellen Nosh-Benutzerterminal (archivierte Version,aktuelle Version). Das Nosh-Paket.
- Jonathan de Boyne Pollard (2017).
Eine verbesserte Manualpage für
ul
(archivierte Version,aktuelle Version). Vorschläge.
Antwort2
Ctrl-H
ist die Rücktaste, sie bewegt den Cursor einen Schritt nach links. Das Senden eines Unterstrichs, einer Rücktaste und eines anderen Zeichens war in der guten alten Zeit die Art und Weise, etwas auf einem Papierterminal zu unterstreichen. Dies wurde verwendet, um den aktuellen Tag in der Ausgabe von hervorzuheben cal
.
Mein cal
Programm konsole
gibt diese Sequenz nicht aus, wenn es ausgeführt wird. Wenn ich es ausführe script -c cal
und die resultierende typescript
Datei untersuche, kann ich sehen, dass das Cal-Programm die Escape-Sequenz verwendet, <esc>[7m
um in den inversen Videomodus zu wechseln.